dee*_*zen 23 c++ multithreading stdmap map
在std :: map中引用对象是否是线程安全的?
std::map< std::string, Object > _objects;
Run Code Online (Sandbox Code Playgroud)
map可以从许多线程更改,并且此访问是同步的,但引用只能从1个实例和线程访问的值(Object&).是否使用Object进行写操作是否安全,如果另一个线程将添加项目到映射?它会重新分配吗?
Yak*_*ont 23
C++ 11标准保证const
对容器的方法访问对于不同的线程是安全的(即两种使用const
方法).
另外,[container.requirements.dataraces]说明
当所包含的对象的内容在相同序列中的不同元素中时,需要实现以避免数据争用,除了
vector<bool>
换句话说,除了vector<bool>
修改不同的内容之外,不是数据竞争.
现在,如果一个线程使另一个线程使用的迭代器无效,显然这是一个数据争用(并导致未定义的行为).如果一个线程不const
访问容器,而另一个线程const
访问,则表示数据争用(以及未定义的行为).(注:一些功能被"视为const
"对多线程的,其中的目的begin
,end
以及其他功能(和是非的方法)const
,只是因为它们返回非const
迭代器. []
包含在这组假的const
线程安全的原因,除了map
和unordered_set
等 - 23.2.2.1).
但是,如果您对容器中的元素有引用,并且参与不会在另一个线程中使该引用无效的操作,并且从不在另一个线程中写入该元素,则可以安全地从该引用中读取.类似地,如果其他线程甚至从未从元素读取,则写入该元素不应导致未定义的行为.
对于标准参考,17.6.5.9.5似乎保证标准库中的函数不会失控并且不必要地读/写元素.
所以简短的回答:你是安全的,只要其他线程没有直接搞乱那个特定的条目map
.
地图中的元素是稳定的,除非从地图中删除元素,否则它们不会被移动或无效.如果只有一个线程正在写入给定对象,并且对地图本身的更改已正确同步,那么我相信它将是安全的.我确信它在实践中是安全的,我认为它在理论上也是安全的.
该标准保证不同的线程可以修改不同的元素,在[container.requirements.dataraces]中
尽管如此(17.6.5.9),当同一序列中不同元素中包含的对象的内容
vector<bool>
同时被修改时,需要实现以避免数据争用.
这只允许您修改元素,而不是在修改元素时将新元素插入到地图中.对于某些容器,例如std::vector
,修改向量本身也可能通过重新分配和移动它们来修改元素,但[associative.reqmts]/9确保std::map
不会使现有元素无效.
由于不需要成员函数std::map
来访问其元素的第二个成员(即mapped_type
),我认为[res.on.data.races]/5表示在修改地图时,其他任何线程都不会与该成员的写入冲突.(感谢Yakk最后一块拼图)