默认情况下 std::vector 是线程安全和并发的吗?为什么或者为什么不?
Is std::vector thread-safe and concurrent by default? Why or why not?
动态数组线程安全和并发是什么意思?
例如,std::vector
.
- 两个线程可能要插入同一位置。不需要同步,因为它将根据线程调度完成。
- 一个线程正在擦除而另一个线程要访问同一个元素?我认为这不是数据结构问题,而是使用问题。
那么在 std::vector
上是否需要做些什么才能使其成为线程安全和并发的,还是默认情况下它是线程安全和并发的?
C++11标准库中关于容器线程安全的规定如下:
23.2.2 Container data races [container.requirements.dataraces]
For purposes of avoiding data races (17.6.5.9), implementations shall
consider the following functions to be const: begin
, end
,
rbegin
, rend
, front
, back
, data
, find
, lower_bound
,
upper_bound
, equal_range
, at
and, except in associative or
unordered associative containers, operator[]
.
Notwithstanding (17.6.5.9), implementations are required to avoid data
races when the contents of the contained object in different elements
in the same sequence, excepting vector<bool>
, are modified
concurrently.
所以,基本上从一个容器中多线程读取是可以的,修改容器中已经存在的元素也是可以的(只要它们是不同的元素)。
所以,对于 std::vector
:
,你的两个更具体的问题都不是线程安全的
1) 插入向量的两个线程正在修改向量本身 - 不存在单独的元素。
2) 一个线程擦除和其他线程访问同一个元素是不安全的,因为从向量中擦除一个元素不是一个承诺线程安全的操作(或 "free from data races",因为标准把它)。
要安全地执行这些操作,需要程序本身施加一些外部同步。
标准库中唯一安全的单个对象的并发操作是
- 仅访问 const
-成员函数
- 对同步原语的所有访问(如互斥锁和解锁或原子操作)
其他一切都必须在外部同步。特别是,标准库还没有任何线程安全容器(截至 c++14)
所以你的两个例子的答案是否定的,它们都需要一种外部同步形式。
当然你可以做的是修改容器中两个不同元素的值。
动态数组线程安全和并发是什么意思?
例如,std::vector
.
- 两个线程可能要插入同一位置。不需要同步,因为它将根据线程调度完成。
- 一个线程正在擦除而另一个线程要访问同一个元素?我认为这不是数据结构问题,而是使用问题。
那么在 std::vector
上是否需要做些什么才能使其成为线程安全和并发的,还是默认情况下它是线程安全和并发的?
C++11标准库中关于容器线程安全的规定如下:
23.2.2 Container data races [container.requirements.dataraces]
For purposes of avoiding data races (17.6.5.9), implementations shall consider the following functions to be const:
begin
,end
,rbegin
,rend
,front
,back
,data
,find
,lower_bound
,upper_bound
,equal_range
,at
and, except in associative or unordered associative containers,operator[]
.Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting
vector<bool>
, are modified concurrently.
所以,基本上从一个容器中多线程读取是可以的,修改容器中已经存在的元素也是可以的(只要它们是不同的元素)。
所以,对于 std::vector
:
1) 插入向量的两个线程正在修改向量本身 - 不存在单独的元素。
2) 一个线程擦除和其他线程访问同一个元素是不安全的,因为从向量中擦除一个元素不是一个承诺线程安全的操作(或 "free from data races",因为标准把它)。
要安全地执行这些操作,需要程序本身施加一些外部同步。
标准库中唯一安全的单个对象的并发操作是
- 仅访问 const
-成员函数
- 对同步原语的所有访问(如互斥锁和解锁或原子操作)
其他一切都必须在外部同步。特别是,标准库还没有任何线程安全容器(截至 c++14)
所以你的两个例子的答案是否定的,它们都需要一种外部同步形式。
当然你可以做的是修改容器中两个不同元素的值。