访问一个std :: map的多线程会导致不安全的行为吗?

时间:2012-09-04 03:10:35

标签: c++

如果多个线程访问一个映射对象,但是,我可以确保访问这些线程中的任何一个都没有相同的密钥,访问就像:

//find value by key
//if find
// erase the object or change the value
//else
// add new object of the key

操作是否会导致同步问题?

3 个答案:

答案 0 :(得分:5)

是的,在没有正确同步的情况下进行并发更新可能会导致崩溃,即使您的线程访问不同的密钥:std::map基于树,树被重新平衡,因此您可以导致写入节点的父节点看似无关的钥匙。

此外,在写入时同时执行只读访问是不安全的,或者在写入时搜索解锁+锁定:如果您有可以更新或删除节点的线程,则必须在写入之前锁定所有读取器。

答案 1 :(得分:2)

如果任何线程插入树中, 会出现并发问题。 STL map是使用红黑树实现的(或者至少是我熟悉的 - 我不知道标准是否要求红黑树)。红黑树可能会在插入时重新平衡,这将导致线程之间的各种比赛。

只读访问权限(绝对没有编写者)没问题,但请记住operator[] 不是只读;它可能会添加一个新元素。您需要使用find()方法,获取迭代器,并自行解除它。

答案 2 :(得分:1)

除非文档(即ISO C ++ 11标准)说它是线程安全的(而且它们没有),那就是它。期。它不是线程安全的。

可能有std :: map的实现允许这样做,但它绝不是可移植的。

地图通常建立在红黑树或其他自动平衡数据结构上,因此对结构进行修改(例如插入或删除密钥)将导致重新平衡。

您应该使用互斥信号量等方式在地图上包装读写操作,以确保正确完成同步。