STL向量和线程安全

发布于 2024-10-06 01:26:54 字数 452 浏览 1 评论 0 原文

假设我有一个包含 N 个元素的向量,但该向量中最多有 n 个元素具有有意义的数据。一个更新线程更新第 n 个或第 n+1 个元素(然后设置 n = n+1),还检查 n 是否太接近 N,并在必要时调用 vector::resize(N+M)。更新后,线程调用多个子线程最多读取第n条数据并进行一些计算。

确保子线程永远不会更改或删除数据(事实上,任何数据都不会被删除),并且更新程序在完成更新后立即调用子线程。

到目前为止还没有出现问题,但是我想问一下,如果上次更新留下了一些子工作线程,在将向量重新分配到更大的内存块时是否会出现问题。
或者在这种多线程情况下使用向量是否安全,因为它不是线程安全的?

编辑: 由于当更新程序调用 vector::resize(N+M,0) 时仅发生插入,因此我的问题有任何可能的解决方案吗?由于 STL 矢量的出色性能,我不愿意用可锁定矢量替换它,或者在这种情况下是否有任何高性能、已知且无锁的矢量?

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.

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?

EDIT:
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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

数理化全能战士 2024-10-13 01:26:54

我想问一下,如果上次更新留下了一些子工作线程,在将向量重新分配到更大的内存块时是否会出现问题。

是的,这会非常糟糕。

如果您从多个线程使用容器,并且至少一个线程可能执行某些可能修改容器状态的操作,则必须同步对容器的访问。

对于 std::vector 来说,任何改变其大小的行为(尤其是插入和擦除)都会改变其状态,即使不需要重新分配(任何插入或擦除都需要 std: :vector 的内部大小簿记数据将被更新)。


解决您的问题的一种方法是让生产者动态分配 std::vector 并使用 std::shared_ptr 。 > 拥有它并将此 std::shared_ptr 提供给每个消费者。

当生产者需要添加更多数据时,它可以动态分配一个新的 std::vector,其具有新的、更大的大小以及旧 std::vector 中元素的副本>。然后,当您派生新的消费者或使用新数据更新消费者时,您只需为新的 std::vector 提供一个 std::shared_ptr 即可。

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).


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.

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.

痴情换悲伤 2024-10-13 01:26:54

您的工作人员决定处理数据线程的方式安全吗?完成的工作人员和生产者之间是否有任何信号传递?如果没有,那么肯定存在一个问题,即生产者可能会导致矢量在仍在处理时移动。尽管这可以通过移至 std::deque 来轻松解决。(请注意,std::deque 会使 push_back 上的迭代器无效,但引用元素不受影响)。

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).

故乡的云 2024-10-13 01:26:54

我制作了自己的 GrowVector。它对我有用,而且速度非常快。

链接:QList、QVector 或 std::vector 多线程用法

I've made my own GrowVector. It works for me and it is really fast.

Link: QList, QVector or std::vector multi-threaded usage

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文