在C++中从/向std :: map读写的线程安全性

Tsv*_*rov 2 c++ stl thread-safety

我有一个多线程应用程序,它使用共享数据结构,包装std :: map.

我知道STL不是线程安全的,同步所有线程是我的工作.另外我认为从列表中插入和删除元素不会使迭代器无效到其他元素.

所以我的代码中有每个元素的锁定,这可以防止两个线程读取/写入同一个元素.让两个线程处理两个不同的对象.它们持有对象的锁,因此其他线程无法修改/删除它们的对象.

但是第三个线程同时尝试删除第三个不同的对象.她已获得锁定,因此没有其他线程会尝试读取或删除它.

当其他线程正在读/写地图的其他元素时,从地图中删除元素是否是线程安全的?

Die*_*ühl 5

请注意,您知道 STL容器不是线程安全的错误!在C++ 2011中,容器提供了合理的线程安全保证.它们可能与您希望的不同,但它们是合理且重要的:

  1. 如果没有线程修改容器的结构,则可以有并发线程读取同一容器对象的结构.
  2. 如果有一个容器结构的编写器,则不能对容器进行其他访问.
  3. 不同的对象是独立的,不同容器对象的并发访问不需要同步.

这些保证意味着如果多个线程只访问容器但不更改其结构,则不需要对容器进行任何同步.由于元素由用户提供,因此根据其线程安全保证,可能需要单独的同步.如果有线程修改容器的结构,则必须正确同步访问.

对于您的情况,您必须确保没有线程读取映射,而某些线程正在修改它.由于迭代器和对象的引用不会失效,因此即使在修改映射时也可以通过迭代器或引用访问映射中的元素 - 当然,除非元素可能被删除.