std :: map的线程安全性,用于只读操作

jil*_*wit 18 c++ multithreading stl stdmap thread-safety

我有一个std :: map,用于将值(字段ID)映射到人类可读的字符串.当我的程序在任何其他线程启动之前启动时,此映射会初始化一次,之后永远不会再次修改.现在,我给每个线程自己的这个(相当大的)地图的副本,但这显然是低效的内存使用,它减慢了程序启动速度.所以我想给每个线程一个指向地图的指针,但这会引发一个线程安全问题.

如果我正在做的就是使用以下代码从地图中读取:

std::string name;
//here N is the field id for which I want the human readable name
unsigned field_id = N; 
std::map<unsigned,std::string>::const_iterator map_it;

// fields_p is a const std::map<unsigned, std::string>* to the map concerned.
// multiple threads will share this.
map_it = fields_p->find(field_id);
if (map_it != fields_p->end())
{
    name = map_it->second;
}
else
{
    name = "";
}
Run Code Online (Sandbox Code Playgroud)

这是否有效或者从多个线程读取std :: map有问题吗?

注意:我目前正在使用visual studio 2008,但我希望这可以在大多数主要的STL实现中使用acros.

更新:已编辑的代码示例,用于const正确性.

lau*_*ura 16

只要您的地图保持不变,这将在多个线程中起作用.您使用的地图事实上是不可变的,因此任何查找实际上都会在地图中进行查找而不会发生变化.

以下是相关链接:http://www.sgi.com/tech/stl/thread_safety.html

STL的SGI实现仅在对不同容器的同时访问是安全的意义上是线程安全的,并且对共享容器的同时读取访问是安全的.如果多个线程访问单个容器,并且至少有一个线程可能写入,则用户负责确保在容器访问期间线程之间的互斥.

你陷入了"共享容器的同时读访问"类别.

注意:这适用于SGI实现.您需要检查是否使用其他实现.在我看来广泛用作替代方案的两种实现中,STLPort具有内置的线程安全性.我不知道Apache的实现.


Use*_*ess 9

应该没问题.const如果要记录/强制执行只读行为,可以使用对它的引用.

注意,不保证正确性(原则上map可以选择在调用时重新平衡自己find),即使你只使用const方法(一个真正有悖常规的实现可以声明树是可变的).但是,这在实践中似乎不太可能.