如果多个线程访问一个映射对象,但是,我可以确保访问这些线程中的任何一个都没有相同的密钥,访问就像:
//find value by key
//if find
// erase the object or change the value
//else
// add new object of the key
操作是否会导致同步问题?
答案 0 :(得分:5)
是的,在没有正确同步的情况下进行并发更新可能会导致崩溃,即使您的线程访问不同的密钥:std::map
基于树,树被重新平衡,因此您可以导致写入节点的父节点看似无关的钥匙。
此外,在写入时同时执行只读访问是不安全的,或者在写入时搜索解锁+锁定:如果您有可以更新或删除节点的线程,则必须在写入之前锁定所有读取器。
答案 1 :(得分:2)
如果任何线程插入树中, 会出现并发问题。 STL map
是使用红黑树实现的(或者至少是我熟悉的 - 我不知道标准是否要求红黑树)。红黑树可能会在插入时重新平衡,这将导致线程之间的各种比赛。
只读访问权限(绝对没有编写者)没问题,但请记住operator[]
不是只读;它可能会添加一个新元素。您需要使用find()
方法,获取迭代器,并自行解除它。
答案 2 :(得分:1)
除非文档(即ISO C ++ 11标准)说它是线程安全的(而且它们没有),那就是它。期。它不是线程安全的。
可能有std :: map的实现允许这样做,但它绝不是可移植的。
地图通常建立在红黑树或其他自动平衡数据结构上,因此对结构进行修改(例如插入或删除密钥)将导致重新平衡。
您应该使用互斥信号量等方式在地图上包装读写操作,以确保正确完成同步。