【发布时间】:2012-09-04 03:10:34
【问题描述】:
如果多个线程访问一个映射对象,但是,我可以确保这些线程中的任何一个访问都不会具有相同的键,并且访问就像:
//find value by key
//if find
// erase the object or change the value
//else
// add new object of the key
操作会不会导致同步问题?
【问题讨论】:
标签: c++
如果多个线程访问一个映射对象,但是,我可以确保这些线程中的任何一个访问都不会具有相同的键,并且访问就像:
//find value by key
//if find
// erase the object or change the value
//else
// add new object of the key
操作会不会导致同步问题?
【问题讨论】:
标签: c++
是的,在没有正确同步的情况下进行并发更新可能会导致崩溃,即使您的线程访问不同的键:std::map 基于树,树会重新平衡,因此您可能会导致写入具有看似无关的键。
此外,在写入的同时执行只读访问,或者搜索解锁+写入锁定是不安全的:如果您有可能更新或删除节点的线程,则必须在写入之前锁定所有读取器。
【讨论】:
如果任何线程插入到树中,您将遇到并发问题。 STL map 是使用红黑树实现的(或者至少这是我所熟悉的——我不知道标准是否要求红黑树)。红黑树可能会在插入时重新平衡,这将导致线程之间的各种竞争。
只读访问权限(绝对 no 写入器)可以,但请记住 operator[] 是非只读的;它可能会添加一个新元素。您需要使用 find() 方法,获取迭代器,然后自行解除引用。
【讨论】:
qsort 是一个快速排序)但是地图是 非常经常以红黑的身份出现。
除非文档(即 ISO C++11 标准)说它是线程安全的(而他们不是),否则就是这样。时期。它不是线程安全的。
可能有 实现 std::map 允许这样做,但它绝不是可移植的。
地图通常建立在红黑树或其他自动平衡数据结构上,因此对结构的修改(例如插入或删除键)将导致重新平衡。
您应该使用诸如互斥信号量之类的东西来包装地图上的读取和写入操作,以确保正确完成同步。
【讨论】: