【问题标题】:Can an std::map be moved while iterating through it?迭代时可以移动 std::map 吗?
【发布时间】:2013-10-16 15:21:59
【问题描述】:

当我遍历std::map 时,是否有可能通过例如在另一个线程中将元素添加到地图中,其中的对象将被删除,从而导致迭代损坏? (因为迭代器在移动时将指向一个不存在的变量)

【问题讨论】:

    标签: c++ iterator thread-safety stdmap


    【解决方案1】:

    理论上,当您向std::map 添加元素时,该映射中的所有迭代器都应该保持有效。但问题是这些操作不是原子的。如果操作系统在操作中间暂停插入线程并将控制权交还给迭代线程,std::map 的状态可能无效。

    您需要通过互斥锁或类似的方式同步对地图的访问。或者,您可以使用来自TBB 或其他类似库的并发友好集合。 TBB 提供concurrent_unordered_mapconcurrent_hash_map

    【讨论】:

    • 一些来自 Microsoft PPL 的 more
    • shared_mutex 就足够了吗? (读取共享锁,写入绝对锁)我真的不知道从地图中读取是否会导致它可能会对其对象或类似的东西进行碎片整理。
    • 从地图中读取不会以任何方式修改它。从多个线程执行此操作是安全的。不应该做的是阅读而其他人写入它。从两个线程写入显然也行不通。
    【解决方案2】:

    STL 容器不是线程安全的。根本没有保证。因此,如果它们被不同的线程使用,您需要同步对任何标准容器的访问。

    【讨论】:

      【解决方案3】:

      是的——如果另一个线程可能正在修改向量,您将需要使用诸如互斥锁之类的东西来确保在任何给定时间只有一个线程可以访问该向量。

      对于地图,修改的影响要有限得多 - 修改不会潜在地移动矢量的全部内容,而只会影响地图中的单个节点。尽管如此,如果一个线程在另一个线程试图读取该节点时删除了一个节点,那么就会发生不好的事情,因此您仍然需要一个互斥锁来确保在任何给定时间只有一个线程在映射上运行。

      【讨论】:

      • 那么std::map 也是这样吗?
      猜你喜欢
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      相关资源
      最近更新 更多