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

时间:2015-01-07 22:28:35

标签: c++ multithreading thread-safety std

我正在尝试为对象设计一个消息队列。有一组X线程可以将消息(稍后处理)发送到此对象。如果我有std::map<thread_id_t, message>,这个线程是否安全,假设线程1只添加密钥为1,线程2为密钥2等的消息。?

2 个答案:

答案 0 :(得分:4)

std::map对于多个同时写入者来说不是线程安全的。

STL映射不是线程安全的众多原因之一是STL映射的底层实现是一个AVL树,需要在多次插入后每隔一段时间重新平衡一次。重新平衡映射会影响多个节点,绝对不是线程安全的。

如果您对此感兴趣,请参阅优秀的Dr. Dobb's article on lock-free data structures

答案 1 :(得分:1)

标准C ++库中类的一般规则是:如果在对象上调用非const方法(除std::vector<T>::operator[]()之类的某些方法外),则不能有任何其他方法线程以任何方式同时访问此对象。如果您需要使用所需的操作,以某种方式同步不同线程之间的访问。标准中的相关条款是17.6.4.10 [res.on.objects]第1段:

  

如果从不同线程调用标准库函数,则程序的行为是未定义的   介绍数据竞赛。可能发生这种情况的条件在17.6.5.9中规定。

...和17.6.5.9 [res.on.data.races],它描述了标准C ++库不允许进行mutate对象,除非调用非const成员函数在他们身上。

由于将对象插入std::map<...>显然是非const操作,因此无法在没有同步的情况下从多个线程同时执行此操作。