std :: vector是否是线程安全的并且默认是并发的?为什么或者为什么不?

时间:2015-06-30 07:07:10

标签: c++ vector data-structures concurrency lock-free

使动态数组线程安全且并发是什么意思? 比方说,std::vector

  1. 两个线程可能想要插入相同的位置。不需要同步,因为它将根据线程调度完成。
  2. 一个线程擦除而另一个线程将访问同一个元素?这不是数据结构问题我认为,这是一个使用问题。
  3. 那么有什么需要在std::vector上完成以使其成为线程安全且并发的,或者它是默认的线程安全和并发的吗?

2 个答案:

答案 0 :(得分:17)

C ++ 11对标准库中容器的安全线程进行了以下说明:

  

23.2.2集装箱数据竞赛[container.requirements.dataraces]

     

为了避免数据竞争(17.6.5.9),实现应该   将以下函数视为const:beginend,   rbeginrendfrontbackdatafindlower_bound,   upper_boundequal_rangeat,以及关联或关联   无序的关联容器,operator[]

     

尽管如此(17.6.5.9),仍需要实施以避免数据   比赛时所包含的对象的内容在不同的元素中   除了vector<bool>之外,在同一序列中进行了修改   同时进行。

因此,基本上从多个线程中读取容器是可以的,并且修改容器中已有的元素就可以了(只要它们是不同的元素)。

因此,对于std::vector,您的两个更具体的问题都不是线程安全的:

1)插入向量的两个线程正在修改向量本身 - 不是现有的单独元素。

2)一个线程擦除和其他步行来访问同一个元素是不安全的,因为从向量中删除一个元素并不是一个承诺线程安全的操作(或者#34;没有数据竞争和&#34; #34;,正如标准所说的那样。)

要安全地执行这些操作,将要求程序自身进行一些外部同步。

答案 1 :(得分:2)

默认情况下,标准库中单个对象的唯一并发操作是安全的   - 仅访问const - 成员函数   - 对同步原语的所有访问(如互斥锁定和解锁或原子操作) 其他一切都必须外部同步。特别是,标准库还没有任何线程安全的容器(从c ++ 14开始)

因此,您的两个示例的答案都是否定的,它们都需要一种外部同步形式。

您可以做的当然是修改容器中两个不同元素的值。