问题描述
假设我有一个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?
推荐答案
是的,这会很糟糕。
容器,并且至少一个线程可以执行可以修改容器的状态的一些动作,对容器的访问必须被同步。
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向量和线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!