我有一个多线程应用程序和一个共享资源std::map<KeyType, ElementType>
。我使用互斥锁来保护插入,获取和删除。
我的get方法返回对存储元素的引用(返回时解锁),然后我对该元素进行一些操作。
问题:使用存储的元素引用时,另一个线程可能会更改std::map
,因此元素将被移动到不同的地址,并且引用将不再有效吗? (我知道某些ADT实现会在调整大小时重新安排ADT。)
答案 0 :(得分:7)
关联容器(std::map
所示)的迭代器失效规则在[associative.reqmts]/9处说明:
插入和安置成员不得影响其有效性 迭代器和对容器的引用,以及擦除成员 仅使迭代器和对已擦除元素的引用无效。
因此,如果一个线程插入一个元素,它将不会影响对现有元素的任何引用。但如果它删除了某些东西,其他线程可能会被堵塞。我会说,某些形式的元素锁定是有序的。
答案 1 :(得分:3)
另一个线程可能会删除元素,或者破坏地图,这当然也会使元素无效。
擦除元素只会使迭代器和对此元素的反思无效。插入不会使迭代器或对地图的引用无效。
(这至少是second-hand documentation says - 而且这是我所持有的假设,如果轶事证据很重要,那就永远不会失效。)
还存在另一个问题:通过返回的引用对元素进行操作不是线程安全的。你需要同步,例如每个元素 - 并确保您不违反锁定层次结构。