STL向量和线程安全 [英] STL vector and thread-safety

查看:162
本文介绍了STL向量和线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个N元素的向量,但这个向量的n元素有有意义的数据。一个更新者线程更新第n或第n + 1个元素(然后设置n = n + 1),还检查n是否太接近N,如果需要,调用vector :: resize(N + M)。更新后,线程调用多个子线程以读取第n个数据并进行一些计算。

Let's say I have a vector of N elements, but up to n elements of this vector have meaningful data. One updater thread updates the nth or n+1st element (then sets n = n+1), also checks if n is too close to N and calls vector::resize(N+M) if necessary. After updating, the thread calls multiple child threads to read up to nth data and do some calculations.

它保证子线程从不改变或删除数据,(实际上没有数据被删除什么这样的),updater调用孩子刚刚完成更新。

It is guaranteed that child threads never change or delete data, (in fact no data is deleted what so ever) and updater calls children just after it finishes updating.

到目前为止没有发生任何问题,但我想问一个问题是否可能发生在重新分配向量到更大的内存块,如果有一些子工作线程

或者在这样的多线程情况下使用向量是安全的,因为它不是线程安全的?

So far no problem has occured, but I want to ask whether a problem may occur during reallocating of vector to a larger memory block, if there are some child working threads left from the previous update.
Or is it safe to use vector, as it is not thread-safe, in such a multithreaded case?

编辑:
因为只有插入发生在updater调用vector :: resize(N + M,0),有没有可能的解决方案我的问题?由于STL向量的伟大性能,我不愿意用可锁定向量替换它,或者在这种情况下是否有任何高性能,已知和无锁向量?

Since only insertion takes place when the updater calls vector::resize(N+M,0), are there any possible solutions to my problem? Due to the great performance of STL vector I am not willing to replace it with a lockable vector or in this case are there any performant,known and lock-free vectors?

推荐答案


我想问一个问题是否可能发生在重新分配向量到较大的内存块,如果有一些子工作线程从上一次更新。 / p>

I want to ask whether a problem may occur during reallocating of vector to a larger memory block, if there are some child working threads left from the previous update.

是的,这会很糟糕。

容器,并且至少一个线程可以执行可以修改容器的状态的一些动作,对容器的访问必须被同步。

If you are using a container from multiple threads and at least one thread may perform some action that may modify the state of the container, access to the container must be synchronized.

std :: vector 的情况下,任何改变其大小(显着地,插入和删除)即使不需要重新分配(任何插入或擦除需要 std :: vector 的内部大小记录数据进行更新),它的状态。

In the case of std::vector, anything that changes its size (notably, insertions and erasures) change its state, even if a reallocation is not required (any insertion or erasure requires std::vector's internal size bookkeeping data to be updated).

您的问题的一个解决方案是让生产者动态分配 std :: vector 并使用 std :: shared_ptr< std :: vector< T> > 拥有它,并为每个消费者提供 std :: shared_ptr

One solution to your problem would be to have the producer dynamically allocate the std::vector and use a std::shared_ptr<std::vector<T> > to own it and give this std::shared_ptr to each of the consumers.

当生产者需要添加更多数据时,它可以动态地分配一个新的,更大的尺寸的新的 std :: vector code> std :: vector 。然后,当你离开新的消费者或更新消费者的新数据,你只需要给他们一个 std :: shared_ptr 新的 std :: vector

When the producer needs to add more data, it can dynamically allocate a new std::vector with a new, larger size and copies of the elements from the old std::vector. Then, when you spin off new consumers or update consumers with the new data, you simply need to give them a std::shared_ptr to the new std::vector.

这篇关于STL向量和线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆