简体   繁体   English

STL矢量和线程安全

[英]STL vector and thread-safety

Let's say I have a vector of N elements, but up to n elements of this vector have meaningful data. 假设我有一个N个元素的向量,但是这个向量的n个元素都有有意义的数据。 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. 一个更新程序线程更新第n个或第n + 1个元素(然后设置n = n + 1),还检查n是否太接近N并在必要时调用vector :: resize(N + M)。 After updating, the thread calls multiple child threads to read up to nth data and do some calculations. 更新后,线程调用多个子线程来读取第n个数据并进行一些计算。

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. 保证子线程永远不会更改或删除数据(实际上没有数据被删除),updater在完成更新后会调用它们。

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? 或者在这样的多线程情况下使用向量是否安全,因为它不是线程安全的?

EDIT: Since only insertion takes place when the updater calls vector::resize(N+M,0), are there any possible solutions to my problem? 编辑:由于只有当updater调用vector :: resize(N + M,0)时才进行插入,我的问题是否有任何可能的解决方案? 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? 由于STL向量的巨大性能,我不愿意用可锁定的向量替换它,或者在这种情况下是否有任何高性能,已知和无锁向量?

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. 我想询问在将向量重新分配给更大的内存块期间是否可能出现问题,如果前一次更新中还有一些子工作线程。

Yes, this would be very bad. 是的,这将是非常糟糕的。

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. 如果您正在使用来自多个线程的容器,并且至少有一个线程可能执行某些可能会修改容器状态的操作,则必须同步对容器的访问。

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::vector的内部大小簿记数据)更新)。


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并使用std::shared_ptr<std::vector<T> >来拥有它并将std::shared_ptr给每个使用者。

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 . 当生产者需要添加更多数据时,它可以动态地分配一个新的std::vector ,它带有一个新的,更大的大小和旧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 . 然后,当您分拆新的消费者或使用新数据更新消费者时,您只需要向新的std::vector提供std::shared_ptr

Is how your workers decide to work on data thread safe? 您的员工是如何决定安全地处理数据线程的? Is there any signaling between workers done and the producer? 工人和制片人之间是否有任何信号? If not then there is definitely an issue where the producer could cause the vector to move while it is still being worked on. 如果没有,那么肯定存在一个问题,即生产者可能会导致向量在仍然处于工作状态时移动。 Though this could trivially be fixed by moving to a std::deque instead.(note that std::deque invalidates iterators on push_back but references to elements are not affected). 虽然这可以通过转移到std::deque来解决这个问题。(请注意, std::deque会使push_back迭代器无效,但对元素的引用不会受到影响)。

I've made my own GrowVector. 我已经制作了自己的GrowVector。 It works for me and it is really fast. 它适用于我,它真的很快。

Link: QList, QVector or std::vector multi-threaded usage 链接: QList,QVector或std :: vector多线程用法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM