[英]std::map thread-safety and iterator invalidation
I'm trying to determine if the following sample code is thread-safe: 我试图确定以下示例代码是否是线程安全的:
std::map<K, V> myMap;
void foo() {
myMap[k]; // Construct a new key-value pair with key `k`.
}
void bar() {
auto it = myMap.find(x);
if (it != myMap.end()) {
std::lock_gaurd<std::mutex> lg(...);
// do something with *it
}
}
There are no removals taking place (atleast until the program is terminating), the only operations are adding elements in foo
and iterating over them in bar
. 不会进行删除(至少要等到程序终止之后),唯一的操作是在
foo
中添加元素并在bar
对其进行迭代。 Function foo
will get called from one thread and bar
will get called in multiple threads, all concurrently. foo
函数将从一个线程调用,而bar
将在多个线程中同时调用。
Now, I understand that the STL containers are not thread-safe and I'm doing a non-const operation concurrently using myMap::operator[]
. 现在,我了解到STL容器不是线程安全的,并且正在使用
myMap::operator[]
同时执行非常量操作。 What I'm confused about is since STL find
doesn't change the underlying map, and because myMap::operator[]
doesn't invalidate iterators nor references, would this still be considered unsafe? 我感到困惑的是,因为STL
find
不会更改基础映射,并且因为myMap::operator[]
不会使迭代器或引用无效,所以这仍然被认为是不安全的吗? I see a bit of a clash in my thinking: should I be worried because operator[]
is non-const and thus I'm doing concurrent changes to the data structure, or can I consider this safe since it won't invalidate my iterator? 我的想法有些冲突:我应该担心,因为
operator[]
是非常量的,因此我正在对数据结构进行并发更改,或者我可以认为这是安全的,因为它不会使我的迭代器无效?
You're right to be suspicious. 你是可疑的是对的。 You can't call
myMap[k]
and myMap.find(x)
from different threads at the same time. 您不能同时从不同的线程调用
myMap[k]
和myMap.find(x)
。
With containers, you can safely do one of the following at a time: 使用容器,您可以一次安全地执行以下操作之一:
Call const member functions from any number of threads concurrently, or 同时从任意多个线程中调用const成员函数,或者
Call a non-const member function from exactly one thread. 仅从一个线程调用非常量成员函数。
Since operator[]
is not const
, you have to guard it with a mutex or otherwise ensure that you're not calling any other member functions at the same time. 由于
operator[]
不是const
,因此必须使用互斥量来保护它,否则请确保不要同时调用任何其他成员函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.