[英]Thread safety of std::map for read-only operations
I have a std::map that I use to map values (field ID's) to a human readable string.我有一个 std::map 用于将值(字段 ID)映射到人类可读的字符串。 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 = "";
}
Will this work or are there issues with reading a std::map from multiple threads?这会起作用还是从多个线程读取 std::map 有问题?
Note: I'm working with visual studio 2008 currently, but I'd like this to work acros most main STL implementations.注意:我目前正在使用 Visual Studio 2008,但我希望它适用于大多数主要的 STL 实现。
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.
您使用的地图事实上是不可变的,因此任何查找实际上都会在不会更改的地图中进行查找。
Here is a relevant link: http://www.sgi.com/tech/stl/thread_safety.html这是一个相关的链接: http : //www.sgi.com/tech/stl/thread_safety.html
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.
STL 的 SGI 实现是线程安全的,仅在对不同容器的同时访问是安全的,对共享容器的同时读取访问是安全的意义上。 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.您属于“对共享容器的同时读取访问”类别。
Note: this is true for the SGI implementation.注意:这适用于 SGI 实现。 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.
在这两种似乎被广泛用作替代方案的实现中,据我所知,STLPort 具有内置的线程安全性。 I don't know about the Apache implementation though.
我不知道 Apache 的实现。
It should be fine.应该没问题。 You can use
const
references to it if you want to document/enforce read-only behaviour.如果您想记录/强制执行只读行为,您可以使用对它的
const
引用。
Note that correctness isn't guaranteed (in principle the map could choose to rebalance itself on a call to find
), even if you do use const methods only (a really perverse implementation could declare the tree mutable).请注意,不能保证正确性(原则上地图可以选择在调用
find
重新平衡自身),即使您只使用 const 方法(一个非常不正常的实现可以声明树可变)。 However, this seems pretty unlikely in practise.然而,这在实践中似乎不太可能。
Yes it is.是的。
See related post with same question about std::set:请参阅有关 std::set 的相同问题的相关帖子:
For MS STL implementation用于 MS STL 实现
Thread Safety in the C++ Standard Library C++ 标准库中的线程安全
The following thread safety rules apply to all classes in the C++ Standard Library—this includes shared_ptr, as described below.
以下线程安全规则适用于 C++ 标准库中的所有类——包括 shared_ptr,如下所述。 Stronger guarantees are sometimes provided—for example, the standard iostream objects, as described below, and types specifically intended for multithreading, like those in .
有时会提供更强的保证——例如,标准 iostream 对象,如下所述,以及专门用于多线程的类型,如 .
An object is thread-safe for reading from multiple threads.
一个对象是线程安全的,可以从多个线程中读取。 For example, given an object A, it is safe to read A from thread 1 and from thread 2 simultaneously.
例如,给定一个对象 A,同时从线程 1 和线程 2 读取 A 是安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.