std::map 中的线程安全
thread safety in std::map
在多线程环境下使用无锁std map安全吗?
保证两个线程永远不会操作映射中的相同条目。
已经有一个问题,但我对多个线程访问映射中不同条目的情况特别感兴趣。特别是无序地图。
只要 none 个线程正在修改地图,它就是安全的。如果线程正在修改映射的不同元素也是安全的(前提是元素本身不会通过例如修改某些全局状态导致竞争条件):
在 17.6.5.9 避免数据竞争 中,标准库保证对容器的并发 const
访问是安全的(至少就容器而言是这样。如果元素允许通过 const
访问进行突变,元素级别可能存在数据竞争。)
在 23.2.2 容器数据竞争中 进一步保证:如果 modifications/reads 是针对不同的 元素,非常量并发访问是安全的 容器1.
一旦您有一个线程对容器或容器中的同一元素进行修改,而其他线程则在读取或写入,您就会面临竞争条件和未定义的行为。
1 除了 std::vector<bool>
根据C++11 23.2.2 Container data races /2
:
Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting vector<bool>
, are modified concurrently.
第 17.6.5.9
部分简单说明了应用到实施的限制,因此 它 不会导致数据竞争。
该文本基本上意味着您必须处理自己的 竞争条件,容器本身不会这样做。
仅访问映射的 const 成员的线程不会相互竞争。这在库类型的要求中指定,在库规范的开头。
访问非常量成员的线程可以与访问常量或非常量成员的线程竞争。
换句话说,它们与任何其他对象几乎一样,没有额外的线程安全保证。标准库目前不包含特殊的线程安全容器。
Is it safe to use std map without a lock in multi-thread environment? Where It is guaranteed that two threads never be manipulating the same entry in the map.
您可以自由地操作地图中不同的现有条目(只有值,因为地图 API 禁止更改键)但是应该使用一些同步工具在任何其他线程尝试访问或更改之前写出更改他们。
对于unordered_map
、insert
(甚至是[]
)、emplace
、erase
、reserve
、rehash
(显式或自动),operator=
、clear
不能安全地完成,而其他线程正在做超过 accessing/mutating 个他们已经找到地址的元素,因为上面的函数可以修改底层哈希 table 数据结构和跟踪元素的每个桶链表。 "more than" 甚至在现有元素上包括 find
、[]
、at
、equal_range
、甚至 empty
、size
和load_factor
和所有 bucket
操作。
在多线程环境下使用无锁std map安全吗? 保证两个线程永远不会操作映射中的相同条目。
已经有一个问题,但我对多个线程访问映射中不同条目的情况特别感兴趣。特别是无序地图。
只要 none 个线程正在修改地图,它就是安全的。如果线程正在修改映射的不同元素也是安全的(前提是元素本身不会通过例如修改某些全局状态导致竞争条件):
在 17.6.5.9 避免数据竞争 中,标准库保证对容器的并发 const
访问是安全的(至少就容器而言是这样。如果元素允许通过 const
访问进行突变,元素级别可能存在数据竞争。)
在 23.2.2 容器数据竞争中 进一步保证:如果 modifications/reads 是针对不同的 元素,非常量并发访问是安全的 容器1.
一旦您有一个线程对容器或容器中的同一元素进行修改,而其他线程则在读取或写入,您就会面临竞争条件和未定义的行为。
1 除了 std::vector<bool>
根据C++11 23.2.2 Container data races /2
:
Notwithstanding (17.6.5.9), implementations are required to avoid data races when the contents of the contained object in different elements in the same sequence, excepting
vector<bool>
, are modified concurrently.
第 17.6.5.9
部分简单说明了应用到实施的限制,因此 它 不会导致数据竞争。
该文本基本上意味着您必须处理自己的 竞争条件,容器本身不会这样做。
仅访问映射的 const 成员的线程不会相互竞争。这在库类型的要求中指定,在库规范的开头。
访问非常量成员的线程可以与访问常量或非常量成员的线程竞争。
换句话说,它们与任何其他对象几乎一样,没有额外的线程安全保证。标准库目前不包含特殊的线程安全容器。
Is it safe to use std map without a lock in multi-thread environment? Where It is guaranteed that two threads never be manipulating the same entry in the map.
您可以自由地操作地图中不同的现有条目(只有值,因为地图 API 禁止更改键)但是应该使用一些同步工具在任何其他线程尝试访问或更改之前写出更改他们。
对于unordered_map
、insert
(甚至是[]
)、emplace
、erase
、reserve
、rehash
(显式或自动),operator=
、clear
不能安全地完成,而其他线程正在做超过 accessing/mutating 个他们已经找到地址的元素,因为上面的函数可以修改底层哈希 table 数据结构和跟踪元素的每个桶链表。 "more than" 甚至在现有元素上包括 find
、[]
、at
、equal_range
、甚至 empty
、size
和load_factor
和所有 bucket
操作。