什么操作在std :: map上是线程安全的?

时间:2010-01-31 04:17:06

标签: c++ multithreading dictionary std c++-standard-library

假设我有:

stl::map<std::string, Foo> myMap;

是以下函数线程安全吗?

myMap["xyz"] ?

即。我希望这个巨大的只读映射在许多线程之间共享;但我不知道连搜索都是线程安全的。


一切都是先写好的。

然后,从中读取多个线程。

我正在努力避免锁定以使其成为尽可能多的事情。 (yaya可能过早优化我知道)

5 个答案:

答案 0 :(得分:11)

理论上,没有STL容器是线程安全的。实际上,如果不同时修改容器,则读取是安全的。即标准没有规定线程。标准的下一个版本将和IIUC一起保证安全的只读行为。

如果您真的担心,请使用带二进制搜索的排序数组。

答案 1 :(得分:11)

C ++ 11要求声明为const的所有成员函数对多个读者都是线程安全的。

调用myMap["xyz"]不是线程安全的,因为std::map::operator[]未声明为const。 尽管如此调用myMap.at("xyz")是线程安全的,因为std::map::at被声明为const

答案 2 :(得分:6)

至少在Microsoft的实现中,从容器中读取是线程安全的(reference)。

但是,std::map::operator[]可以修改数据,而不是const。您应该使用std::map::find const来获取const_iterator并取消引用它。

答案 3 :(得分:4)

理论上,只读数据结构和函数不需要任何线程安全锁。它本质上是线程安全的。并发内存读取有无数据竞争。但是,您必须保证只通过一个线程进行安全初始化。

正如Max S.所指出的,大多数在myMap["xyz"]等地图中读取元素的实现都没有写入操作。如果是这样,那么它是安全的。但是,再一次,您必须保证除了初始化阶段之外没有修改结构的线程。

答案 4 :(得分:1)

STL集合不是线程安全的,但将线程安全性添加到其中非常简单。

最好的办法是在相关集合周围创建一个线程安全的包装器。