【问题标题】:Concurrent hash table in C++C++中的并发哈希表
【发布时间】:2020-01-29 00:16:28
【问题描述】:

在我的应用程序中,我基本上有多个线程来执行插入操作,并且主要是一个线程遍历映射并在满足某些条件时删除项目。我想使用并发结构的原因是它会在代码中提供更细粒度的锁定,以从队列中删除看起来与此类似的项目,这并不理想,原因包括线程在持有时可能被抢占锁。

Function_reap()
{
   while(timetaken != timeoutTime)
   {
      my_map_mutex.lock();

      auto iter = my_unordered_map.begin();
      while(iter != my_unordered_map.end())
      {
        if(status_completed == iter->second.status)
        {
          iter = my_unordered_map.erase(iter);
        }
      }

      my_map_mutex.unlock();
   }
}

正在阅读英特尔 TBB(线程构建模块)的文档,更具体地说,是 concurrent_unordered_map 文档 (https://software.intel.com/en-us/node/506171),以查看这是否适合我的应用程序并看到了这段摘录。

说明 concurrent_unordered_map 和 concurrent_unordered_multimap 支持并发插入和 遍历,但不是并发擦除。接口没有可见 锁定。他们可能在内部持有锁,但在调用时绝不会 用户定义的代码。它们的语义类似于 std::unordered_map 和 std::unordered_multimap 分别,除了如下:

  • erase 和 extract 方法以 unsafe_ 为前缀,表示它们不是并发安全的。
  • 为什么 TBB 不提供从地图中安全同步删除?这是什么技术原因?
  • 如果我在这里还有其他选择怎么办?理想情况下,绝对可以在 Linux 上运行,如果可能的话,可以移植到 Windows。

【问题讨论】:

    标签: c++ multithreading tbb


    【解决方案1】:

    嗯,很难设计一个(有效地)支持所有操作的解决方案。 TBB 有concurrent_unordered_map 支持并发插入、查找和迭代,但不支持擦除 - 和concurrent_hash_map 支持并发插入、查找和擦除,但不支持迭代。

    还有其他几个提供并发哈希映射的库,比如 libcds,或者我自己的一个叫做 xenium

    ATM xenium 包含两个并发哈希映射实现:

    • harris_michael_hash_map - 完全无锁;支持并发插入、擦除、查找和迭代。但是,桶的数量必须在构建时定义,并且不能在之后进行调整。每个桶都包含一个项目的链表,这对缓存不是很友好。
    • vyukov_hash_map - 是一个非常快速的哈希映射,它使用细粒度锁定进行插入、擦除和迭代;查找操作是无锁的。但是,如果使用迭代器,则必须小心避免死锁(即,线程不应在持有迭代器时尝试插入或擦除键)。但是,存在需要迭代的擦除重载,因此您可以安全地删除迭代器指向的项目。

    我目前正在努力使 xenium 与 Windows 完全兼容。

    【讨论】:

    • 感谢您的指点,不胜感激。将查看这两个并尝试一下。
    • 在 vyukon_hash_map 上跟进问题。您提到的死锁场景在一般层面上是有意义的 - 这种死锁场景是否也适用于从地图中删除\删除?我希望不会,如果它不想听到你解释为什么插入死锁而不是擦除如果在迭代的同一线程上执行。
    • 是的,不幸的是,死锁场景也适用于修改哈希映射的其他操作,因此必须获取存储桶锁(即,emplace、erase、extract)。但是,有一个带有迭代器的擦除重载,因此您可以安全地删除迭代器指向的项目。
    • 我已经编辑了我的原始答案以清楚地传达这一点。
    • 感谢您的回答,很高兴听到有支持这一点的过载。我在更一般的层面上对此进行了更多思考......这种死锁场景可以通过使用递归互斥锁之类的东西消失吗?
    猜你喜欢
    • 2012-02-22
    • 1970-01-01
    • 2014-01-24
    • 2023-03-04
    • 2013-08-20
    • 2012-10-03
    • 2019-03-26
    • 1970-01-01
    相关资源
    最近更新 更多