C ++中向量和列表的非写成员函数的线程安全性

时间:2017-07-17 09:48:00

标签: c++ multithreading c++11 thread-safety mutex

如果我正在访问std :: vector或std :: list的成员函数,那么它是线程安全的吗?

示例:

struct ABC
{
...
}

std::vector<ABC> vecofAbc;

以下操作线程是否安全,因为它们刚刚被读取?

vecofAbc.at(1) ;
ABC::iterator iter = vecofAbc.end();
ABC::iterator iter = vecofAbc.begin();

类似于std :: list thread safe的上述成员函数?

我知道push_back()不会是线程安全的,因为它是写的。

5 个答案:

答案 0 :(得分:4)

读取是线程安全的,只要没有并行写入,就不需要同步机制。

答案 1 :(得分:4)

读取操作不是线程安全的。如果在执行读操作时修改了容器,则存在数据争用,并且行为未定义。

读取操作本身不会创建种族编码,因此多次读取不需要相互同步 - 仅与修改有关。

答案 2 :(得分:1)

当一个方法不受同时读取或写入相同数据的其他线程的影响时,称该方法是线程安全的。因此,您只进行读取的事实实际上是无关紧要的。你提到的方法不是线程安全的,因为如果有第二个线程同时修改向量,你就会有数据竞争。

PS:不过,如果你只是从矢量中读取你不需要线程安全,因为没有数据竞争,并且everthing很好。

答案 3 :(得分:1)

最好将C ++中的线程安全视为单个操作的属性,而不是相互之间多个操作的属性。

vecofAbc.at(1) ;
ABC::iterator iter = vecofAbc.end();
ABC::iterator iter = vecofAbc.begin();

这些都是相互线程安全的。它们可以在单独的线程中出现,不涉及数据争用。

通过上述操作,存在相互线程安全的操作。其中包括

vecofAbc.push_back(some_abc);
vecofAbc.reserve(10000);

还要注意

vecofAbc[0] = some_abc;

是相互线程安全的
vecofAbc.at(1);

vecofAbc[1] = some_abc;

规则是容器上的任意数量的const操作都是mutualy线程安全的,.begin()end()和许多其他操作(不会改变容器布局) )就此规则而言,被视为const

此外,读取/写入元素对于从不同元素读取/写入是相互线程安全的,并且对元素的读取/写入与容器上的其他const操作相互线程安全(和通过上述规则将视为const 的其他操作。)

std::vector保证只有在通过const方法调用自身时或在上述规则下通过作为const 处理的方法调用类上的const方法时。如果您的对象的const方法无法保证相互线程安全,则所有投注均已关闭。

有关详细信息,请参阅Does const mean thread safe

答案 4 :(得分:0)

如果你可以保证只有对这个向量的读访问权,那么是的,从多个线程做到这一点是安全的。只有在线程改变某些内容时才会出现问题。