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

Thread safety of the non-write member functions of vectors and lists in C++

本文关键字:成员 函数 安全性 线程 向量 列表 C++      更新时间:2023-10-16

如果我正在访问 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 线程成员函数是否安全?

我知道 push_back(( 在写入时不会是线程安全的。

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

读取操作本身不会创建竞争编码,因此多个读取不需要彼此同步 - 只需与修改相关。

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

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

PS:尽管如此,如果您只从向量中读取,则不需要线程安全,因为没有数据竞争,一切都很好。

最好不要将线程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操作都是相互线程安全的,并且就此规则而言,.begin()end()和许多其他操作(不会改变容器布局(被视为const

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

std::vector保证它只会在通过const方法或通过上述规则下被视为 const的方法调用类const方法时调用类。 如果对象的const方法无法相互线程安全,则所有赌注都将关闭。

有关更多详细信息,请参阅const是否意味着线程安全。

如果您可以保证只有对此向量的读取访问权限,那么是的,从多个线程执行此操作是安全的。只有当线程更改某些内容时,才会出现问题。