并发向量<bool>

时间:2015-11-09 20:13:42

标签: c++ multithreading c++11 vector

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

但是写作操作也不能说。但是,我想知道这是否总是如此,例如考虑我的特定情况。

我有一个std::vector<bool>,其中所有元素都被初始化为false,并且,给定一个索引数组,我需要更改这些元素的值(vector[index]索引)从falsetrue

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

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

2 个答案:

答案 0 :(得分:16)

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

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

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

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

  

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

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

答案 1 :(得分:11)

[container.requirements.dataraces] / 2说:

  

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

因此,当容器为vector<bool>时,您可以安全地从不同的线程 修改同一标准库容器的不同元素。