简体   繁体   English

std :: map线程安全和迭代器无效

[英]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: 使用容器,您可以一次安全地执行以下操作之一:

  1. Call const member functions from any number of threads concurrently, or 同时从任意多个线程中调用const成员函数,或者

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM