STL 向量和线程安全

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

保证子线程永远不会更改或删除数据,(实际上没有数据被删除)并且更新程序在完成更新后立即调用子线程.

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

由于只有在更新程序调用 vector::resize(N+M,0) 时才会进行插入,所以我的问题有什么可能的解决方案吗?由于 STL 向量的出色性能,我不愿意用可锁定向量替换它,或者在这种情况下是否有任何高性能、已知和无锁向量?

b070206074 回答:STL 向量和线程安全

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

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.

是的,这会很糟糕.

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

在 std::vector 的情况下,任何改变其大小的东西(特别是插入和擦除)都会改变它的状态,即使不需要重新分配(任何插入或擦除都需要 std::vector 要更新的内部大小簿记数据).

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

当生产者需要添加更多数据时,它可以动态分配一个新的std::vector,它具有新的、更大的尺寸和旧std::vector 元素的副本.然后,当您剥离新消费者或使用新数据更新消费者时,您只需将 std::shared_ptr 赋予新的 std::vector.

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

本文链接:https://www.f2er.com/3186441.html

大家都在问