17

假设我有:

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

以下函数线程安全吗?

myMap["xyz"] ?

即我想拥有这个在许多线程之间共享的巨大只读映射;但我不知道即使搜索它是否是线程安全的。


一切都先写入一次。

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

我试图避免锁定以使其尽可能快。(我知道,yaya 可能过早优化)

4

5 回答 5

16

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

调用myMap["xyz"]不是线程安全的,因为std::map::operator[]没有声明为const. 调用myMap.at("xyz")是线程安全的,因为std::map::at声明为const.

于 2013-05-04T11:26:07.683 回答
11

理论上没有 STL 容器是线程安全的。在实践中,如果容器没有被同时修改,读取是安全的。即该标准没有关于螺纹的规范。该标准的下一个版本将和 IIUC 将保证安全的只读行为。

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

于 2010-01-31T04:41:59.047 回答
6

至少在微软的实现中,从容器中读取是线程安全的(参考)。

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

于 2010-01-31T04:42:51.990 回答
4

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

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

于 2010-01-31T05:00:01.983 回答
1

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

你最好的选择是围绕有问题的集合创建一个线程安全的包装器。

于 2010-01-31T04:31:38.583 回答