C++ std::map中的线程安全

C++ std::map中的线程安全,c++,c++11,stl,C++,C++11,Stl,在多线程环境中使用无锁std map安全吗? 保证两个线程永远不会操作映射中的同一个条目 这方面已经有一个问题,但我特别感兴趣的是多个线程正在访问映射中的不同条目的情况。尤其是无序映射。只要没有线程修改映射,就安全了。如果线程正在修改映射的不同元素(前提是这些元素本身不会通过修改某些全局状态等方式导致争用条件),这也是安全的: 在17.6.5.9数据竞争避免中,标准库保证对容器的并发const访问是安全的(至少在容器的运行范围内。如果元素允许通过const访问进行变异,则元素级别可能存在数据竞争

在多线程环境中使用无锁std map安全吗? 保证两个线程永远不会操作映射中的同一个条目


这方面已经有一个问题,但我特别感兴趣的是多个线程正在访问映射中的不同条目的情况。尤其是无序映射。

只要没有线程修改映射,就安全了。如果线程正在修改映射的不同元素(前提是这些元素本身不会通过修改某些全局状态等方式导致争用条件),这也是安全的:

17.6.5.9数据竞争避免中,标准库保证对容器的并发
const
访问是安全的(至少在容器的运行范围内。如果元素允许通过
const
访问进行变异,则元素级别可能存在数据竞争)

23.2.2容器数据竞争中进一步保证:如果修改/读取的是容器的不同元素,则非常量并发访问是安全的1

一旦有一个线程在其他线程读写时对容器或容器中的同一元素进行修改,您就会面临竞争条件和未定义的行为



根据
C++11 23.2.2容器数据竞赛/2
,除
std::vector

外:

尽管有(17.6.5.9)的规定,但当同时修改同一序列中不同元素(向量
除外)中包含的对象的内容时,需要实现以避免数据竞争

第17.6.5.9节仅说明了应用于实现的限制,以免引起数据争用


该文本基本上意味着您必须处理自己的竞争条件,容器本身不会这样做。

仅访问映射的常量成员的线程不会彼此竞争。这在库规范开头的库类型要求中有规定

访问非常量成员的线程可以与访问常量或非常量成员的线程竞争

换句话说,它们与任何其他对象几乎一样,没有额外的线程安全保证。标准库当前不包含特殊的线程安全容器

在多线程环境中使用无锁std map安全吗?保证两个线程永远不会操作映射中的同一个条目

您可以自由地操作映射中不同的现有条目(只有值,因为映射API禁止对键进行变异),但应该在任何其他线程尝试访问或变异它们之前使用一些同步工具写出更改


对于
无序映射
插入
(即使通过
[]
),
放置
擦除
保留
重新刷新
(显式或自动),
运算符=
clear
无法安全地完成,因为其他线程所做的不仅仅是访问/变异它们已经找到的元素的地址,因为上述函数可以修改底层哈希表数据结构和跟踪元素的每桶链表。“超过”包括
查找
[]
即使在现有元素上,
处,
相等范围
大小
装载系数
以及所有
操作。

向量
外的“所有标准库容器”,虽然我想你可以说那一个不算容器;)@T.C.恶心。还有人真的在用那个东西吗?@T.C.说得对。我不认为它是一个容器,但值得指出这一点。“McCgLISSE是的,我认为脚注应该在第一段第二句的结尾。对于容器来说,某些非const函数是可以同时使用的(例如,<代码>开始)< /代码> /<代码>结束)(< /代码> /<代码>前端()/代码> /<代码>后退()/代码>等)。