我有一个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 = "";
}
这项工作或从多个线程读取std :: map会有问题吗?
[注意:我目前正在使用Visual Studio 2008,但是我希望此功能可以支持大多数主要的STL实现。
更新:为常量正确性而编辑的代码示例。
这将在多个线程中起作用,只要您的地图保持不变。您使用的地图实际上是不可变的,因此任何查找实际上都会在不会更改的地图中进行查找。
这里是相关链接:http://www.sgi.com/tech/stl/thread_safety.html
STL的SGI实现是线程安全仅在以下意义上同时访问不同容器安全且同步读取对共享容器的访问很安全如果有多个线程访问一个容器,至少一个线程可能潜在地写,然后用户负责确保线程之间的互斥在访问容器期间。
您属于“对共享容器的同时读取访问”类别。
注意:对于SGI实现,这是正确的。您需要检查是否使用其他实现。据我所知,在似乎被广泛用作替代方案的两种实现中,STLPort具有内置的线程安全性。我不了解Apache的实现。
应该没问题。如果要记录/强制执行只读行为,可以使用const
引用。
请注意,即使您仅使用const方法(实际上不正确的实现可能声明树可变),也无法保证正确性(原则上,映射可以选择在调用find
时重新平衡自身)。但是,实际上这似乎不太可能。
对于MS STL实施