并发向量<bool>

Nic*_*ick 9 c++ multithreading vector c++11

我知道可以从std::vector没有"坏"结果的同时读取,因为这个操作可以被认为是线程安全的.

但是对于写作操作也是如此.但是,我想知道这是不是真的,例如考虑我的特殊情况.

我有个std::vector<bool>,其中的所有元素初始化为false,和,给定索引的阵列,我需要改变这些元件的值(vector[index]对于每个指数)从falsetrue.

如果我为每个索引使用不同的线程(并且某些索引可能具有相同的值),是否可以将此操作视为线程安全的?

如果向量是std::vector<int>(或任何基本类型)并且赋值的值始终相同(例如1),此操作仍然可以被认为是线程安全的吗?

Fel*_*bek 18

并发写入vector<bool>永远不会正常,因为底层实现依赖于类型的代理对象,vector<bool>::reference其行为就好像它是对bool的引用,但实际上将根据需要获取和更新位域字节.

在没有同步的情况下使用多个线程时,可能会发生以下情况:线程1应该更新一位,并读取包含它的字节.然后线程2读取相同的字节,然后线程1更新一位并将字节写回,然后线程2更新另一位并写回字节,覆盖线程1的编辑.

这只是一种可能的情况,还有一些会导致同样的数据损坏.


在这种vector<int>情况下,如果您完全确定所有线程都将相同的值写入向量,则此操作通常不会导致数据损坏.但是,标准当然总是格外小心,并定义对内存位置的所有并发访问,其中至少有一个是写访问,是未定义的行为:

如果其中一个修改内存位置而另一个读取或修改相同的内存位置,则两个表达式评估会发生冲突.- intro.races/2

因此,只要对来自两个不同线程的同一元素执行任何修改操作,您就会遇到竞争条件并需要正确同步,例如使用std::atomic<int>.

  • "在vector <int>情况下,如果您完全确定所有线程都将相同的值写入向量,那么此操作将永远不会导致数据损坏." - 这是不正确的,对同一内存位置的并发写入会导致未定义的行为,无论要写入的值是否相同.引用[(intro.races/2)](https://timsong-cpp.github.io/cppwp/n4659/intro.races):"如果其中一个修改了内存位置而另一个修改了内存位置,则两个表达式评估会发生冲突一个人读取或修改相同的记忆位置." (3认同)

Cas*_*sey 13

[container.requirements.dataraces]/2说:

尽管如此(17.6.5.9),除了vector<bool>同时修改同一容器中不同元素中的包含对象的内容之外,还需要实现以避免数据争用.

因此,您可以安全地从不同的线程修改同一标准库容器的不同元素,除非该容器是vector<bool>.