3

如果多个线程访问一个映射对象,但是,我可以确保这些线程中的任何一个访问都不会具有相同的键,并且访问就像:

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

操作会不会导致同步问题?</p>

4

3 回答 3

5

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

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

于 2012-09-04T03:13:55.557 回答
2

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

只读访问(绝对没有写入器)会很好,但请记住不是operator[]只读的;它可能会添加一个新元素。您需要使用该方法,获取迭代器,然后自己取消引用。find()

于 2012-09-04T03:19:09.917 回答
1

除非文档(即 ISO C++11 标准)说它是线程安全的(而他们不是),否则就是这样。时期。它不是线程安全的。

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

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

您应该使用诸如互斥信号量之类的东西来包装映射上的读取和写入操作,以确保正确完成同步。

于 2012-09-04T03:13:05.417 回答