2010-01-31 314 views
13

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

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

是下面的函数线程安全的?

myMap["xyz"] ? 

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

谢谢!

编辑:

一切都写入一次第一。

然后,多线程读取它。

我试图避免锁使尽可能的尽可能多。 (我知道yaya可能过早优化)

回答

11

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

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

2

STL集合不是线程安全的,但是为一个线程安全添加相当简单。

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

6

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

但是,std::map::operator[]可以修改数据并且未声明const。你应该使用std::map::find,这是const,得到一个const_iterator并取消它。

+0

为了在容器中有任何东西,它需要被写入。因此,线程安全问题... – 2010-01-31 04:51:19

+1

这些问题指定我们正在查看只读地图。我认为这意味着它在从多个线程读取之前完全填充到一个线程中。 – 2010-01-31 05:24:12

4

从理论上讲,只读数据结构和函数不需要任何锁定用于线程安全。它本质上是线程安全的。有没有数据竞争并发内存读取。但是,只能通过一个线程来保证安全的初始化。

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

7

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

调用myMap["xyz"]不是线程安全的,因为std::map::operator[]未声明为const。 虽然呼叫myMap.at("xyz")是线程安全的,因为std::map::at被声明为const

相关问题