如果不同的线程总是使用不同的键,它们可以插入到映射中吗?

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 操作,您不能在没有同步的情况下从多个线程并发执行此操作。