如果不同的线程总是使用不同的键,它们可以插入到映射中吗?
Can different threads insert into a map if they always use different keys?
我正在尝试为对象设计消息队列。有一组 X 线程都可以向这个对象发送消息(稍后处理)。如果我有一个 std::map<thread_id_t, message>
,这个线程安全吗,假设线程 1 只添加密钥为 1 的消息,线程 2 到密钥 2,等等。?
std::map
对于多个同时写入者来说不是线程安全的。
STL 映射不是线程安全的众多原因之一是,STL 映射的底层实现是一个 AVL 树,在多次插入后需要每隔一段时间重新平衡一次。重新平衡地图会影响多个节点,并且绝对不是线程安全的。
如果您觉得其中任何一个有趣,请参阅优秀的 Dr. Dobb's article on lock-free data structures。
标准 C++ 库中 类 的一般规则是:如果您在对象上调用非 const
方法(某些方法除外,例如 std::vector<T>::operator[]()
) 你不能让任何其他线程以任何方式同时访问这个对象。如果您需要使用操作,您需要以某种方式同步不同线程之间的访问。标准中的相关条款为17.6.4.10 [res.on.objects] paragraph 1:
The behavior of a program is undefined if calls to standard library functions from different threads may
introduce a data race. The conditions under which this may occur are specified in 17.6.5.9.
... 和 17.6.5.9 [res.on.data.races] 描述标准 C++ 库不允许对对象进行变异,除非在对象上调用非 const
成员函数.
由于将对象插入 std::map<...>
显然是非 const
操作,您不能在没有同步的情况下从多个线程并发执行此操作。
我正在尝试为对象设计消息队列。有一组 X 线程都可以向这个对象发送消息(稍后处理)。如果我有一个 std::map<thread_id_t, message>
,这个线程安全吗,假设线程 1 只添加密钥为 1 的消息,线程 2 到密钥 2,等等。?
std::map
对于多个同时写入者来说不是线程安全的。
STL 映射不是线程安全的众多原因之一是,STL 映射的底层实现是一个 AVL 树,在多次插入后需要每隔一段时间重新平衡一次。重新平衡地图会影响多个节点,并且绝对不是线程安全的。
如果您觉得其中任何一个有趣,请参阅优秀的 Dr. Dobb's article on lock-free data structures。
标准 C++ 库中 类 的一般规则是:如果您在对象上调用非 const
方法(某些方法除外,例如 std::vector<T>::operator[]()
) 你不能让任何其他线程以任何方式同时访问这个对象。如果您需要使用操作,您需要以某种方式同步不同线程之间的访问。标准中的相关条款为17.6.4.10 [res.on.objects] paragraph 1:
The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race. The conditions under which this may occur are specified in 17.6.5.9.
... 和 17.6.5.9 [res.on.data.races] 描述标准 C++ 库不允许对对象进行变异,除非在对象上调用非 const
成员函数.
由于将对象插入 std::map<...>
显然是非 const
操作,您不能在没有同步的情况下从多个线程并发执行此操作。