只读操作的 std::map 线程安全

2022-01-07 00:00:00 multithreading thread-safety c++ stl stdmap

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

I have a std::map that I use to map values (field ID's) to a human readable string. This map is initialised once when my program starts before any other threads are started, and after that it is never modified again. Right now, I give every thread its own copy of this (rather large) map but this is obviously inefficient use of memory and it slows program startup. So I was thinking of giving each thread a pointer to the map, but that raises a thread-safety issue.

如果我所做的只是使用以下代码读取地图:

If all I'm doing is reading from the map using the following code:

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 有问题?

Will this work or are there issues with reading a std::map from multiple threads?

注意:我目前正在使用 Visual Studio 2008,但我希望它适用于大多数主要的 STL 实现.

Note: I'm working with visual studio 2008 currently, but I'd like this to work acros most main STL implementations.

更新:编辑代码示例以确保常量正确性.

Update: Edited code sample for const correctness.

推荐答案

只要您的地图保持不变,这将适用于多个线程.您使用的地图实际上是不可变的,因此任何查找实际上都会在不会更改的地图中进行查找.

This will work from multiple threads as long as your map remains the same. The map you use is immutable de facto so any find will actually do a find in a map which does not change.

这是一个相关链接:http://www.sgi.com/tech/stl/thread_safety.html

STL 的 SGI 实现是线程安全仅在这种意义上同时访问不同的容器是安全的,同时对共享容器的读访问是安全的.如果多个线程访问一个单个容器,以及至少一个线程可能会写,那么用户有责任确保线程之间的互斥在容器访问期间.

The SGI implementation of STL is thread-safe only in the sense that simultaneous accesses to distinct containers are safe, and simultaneous read accesses to to shared containers are safe. If multiple threads access a single container, and at least one thread may potentially write, then the user is responsible for ensuring mutual exclusion between the threads during the container accesses.

您属于对共享容器的同时读取访问"类别.

You fall into he "simultaneous read accesses to shared containers" category.

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

Note: this is true for the SGI implementation. You need to check if you use another implementation. Of the two implementations which seem widely used as an alternative, STLPort has built-in thread safety as I know. I don't know about the Apache implementation though.

相关文章