C++ 用于只读操作的 std::map 线程安全
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1846186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thread safety of std::map for read-only operations
提问by jilles de wit
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.
我有一个 std::map 用于将值(字段 ID)映射到人类可读的字符串。当我的程序在启动任何其他线程之前启动时,此映射会被初始化一次,之后就不再被修改。现在,我给每个线程自己的这个(相当大)映射的副本,但这显然是内存的低效使用,并且会减慢程序启动速度。所以我想给每个线程一个指向地图的指针,但这引发了一个线程安全问题。
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.
更新:编辑代码示例以确保常量正确性。
采纳答案by laura
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. 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.
STL 的 SGI 实现是线程安全的,仅在对不同容器的同时访问是安全的,对共享容器的同时读访问是安全的。如果多个线程访问单个容器,并且至少有一个线程可能会写入,则用户负责确保容器访问期间线程之间的互斥。
You fall into he "simultaneous read accesses to shared containers" category.
您属于“对共享容器的同时读取访问”类别。
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.
注意:这适用于 SGI 实现。您需要检查是否使用其他实现。在这两种似乎被广泛用作替代方案的实现中,据我所知,STLPort 具有内置的线程安全性。我不知道 Apache 的实现。
回答by Useless
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). However, this seems pretty unlikely in practise.
请注意,不能保证正确性(原则上映射可以选择在调用 时重新平衡自身find
),即使您只使用 const 方法(一个非常不正常的实现可以声明树可变)。然而,这在实践中似乎不太可能。
回答by RED SOFT ADAIR
Yes it is.
是的。
See related post with same question about std::set:
请参阅有关 std::set 的相同问题的相关帖子:
回答by Bogdan Vasilescu
For MS STL implementation
用于 MS STL 实现
Thread Safety in the C++ Standard Library
The following thread safety rules apply to all classes in the C++ Standard Library—this includes shared_ptr, as described below. Stronger guarantees are sometimes provided—for example, the standard iostream objects, as described below, and types specifically intended for multithreading, like those in .
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.
以下线程安全规则适用于 C++ 标准库中的所有类——包括 shared_ptr,如下所述。有时会提供更强的保证——例如,标准 iostream 对象,如下所述,以及专门用于多线程的类型,如 .
一个对象是线程安全的,可以从多个线程中读取。例如,给定一个对象 A,同时从线程 1 和线程 2 读取 A 是安全的。