假设我有:
stl::map<std::string, Foo> myMap;
是以下函数线程安全吗?
myMap["xyz"] ?
即。我希望这个巨大的只读映射在许多线程之间共享;但我不知道连搜索都是线程安全的。
一切都是先写好的。
然后,从中读取多个线程。
我正在努力避免锁定以使其成为尽可能多的事情。 (yaya可能过早优化我知道)
答案 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集合不是线程安全的,但将线程安全性添加到其中非常简单。
最好的办法是在相关集合周围创建一个线程安全的包装器。