【问题标题】:Concurrent_hash_map implementation throwing SIGSEGVConcurrent_hash_map 实现抛出 SIGSEGV
【发布时间】:2018-09-02 17:49:26
【问题描述】:

我正在尝试使用 tbb 的 concurrent_hash_map 来提高我的应用程序的并发性能。阅读它并根据我的应用程序实现它,但我看到崩溃..

所以,我的应用程序是一个多线程应用程序,我在其中存储对,键是 char*,值是整数。伪代码如下:

在.h文件中,

typedef tbb::concurrent_hash_map<const void*, unsigned, Hasher> tbb_concurrent_hash;
tbb_concurrent_hash concurrent_hash_table;
tbb_concurrent_hash::accessor  write_lock;
tbb_concurrent_hash::const_accessor read_lock;

在.c文件中,

void  storeName(const char * name)   {
    int id=0;

    // This creates a pair object of name and index
    std::pair object(name, 0);

    // read_lock is a const accessor for reading. This find function searches for char* in the table and if not found, create a write_lock.

    bool found = concurrent_hash_table.find(read_lock, name);  
    if (found == FALSE) {
      concurrent_hash_table.insert(write_lock, name);
      // Get integer id somehow.
      id = somefunction();
      write_lock->second = id; 
      write_lock.release();         
    } else {
      // if the name is found in the table then get the value and release it later
      id = read_lock->second;
      read_lock.release();
    }
}

根据我的理解,我对实现很满意,但正如我所说,当 find 返回 FALSE 时会发生多次崩溃。崩溃也有互斥的痕迹。

【问题讨论】:

  • 为什么会有read_lockwrite_lock?你能说明它们是如何声明的吗?
  • @orhtej2,编辑了问题。抱歉没有早点写。干杯!
  • 另请参阅此文档 - 我认为您可以简化您的解决方案:threadingbuildingblocks.org/docs/help/index.htm#reference/…
  • @WillBickford,你建议什么样的简化?超载?我以为我有相当简单的实现。
  • 文档指出,如果您的密钥已经存在,insert 将返回 false,因此您应该能够完全消除查找,因为如果它不存在,您总是插入。

标签: c++ multithreading concurrency hashmap tbb


【解决方案1】:

您的“锁”,即访问器在 .h 文件中被声明为全局的。所以,基本上你写入一个共享的 scoped_lock 实例......这在逻辑上会导致数据竞争。访问器就像融合了 std::shared_ptr 和 std::scoped_lock 类,或者更简单——结果的指针和它指向的数据的锁守卫。您不想使用来自多个线程的一个全局指针。在您想要访问的范围内本地声明它们(您也不需要调用.release()

另一个问题是 find() 和 insert() 之间的数据竞争。两个或多个线程可以决定他们必须插入,因为他们什么也没找到。在这种情况下,第一个线程将插入新元素,而其他线程将返回现有元素,因为如果存在现有元素,则 insert() 充当 find()。问题是您的代码没有考虑到这一点。

我明白为什么您可能要使用 const_accessor 进行仔细检查,因为读锁更具可扩展性。但是,您可能希望将bool insert( const_accessor&amp; result, const value_type&amp; value ); 与读取锁 (const_accessor) 和 value_type 一起使用,而不是仅使用键,这将在添加新元素时初始化整个对。

【讨论】:

  • 感谢您指出。我明白你的意思。使它们本地化。您还发现其中还有什么问题吗?
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
相关资源
最近更新 更多