Concurrent_hash_map实现抛出SIGSEGV

时间:2018-09-02 17:49:26

标签: c++ multithreading concurrency hashmap tbb

我正在尝试使用tbb的current_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时会发生多次崩溃。崩溃也有互斥的痕迹。

1 个答案:

答案 0 :(得分:4)

您的“锁”,即访问器在.h文件中声明为全局。因此,基本上,您将写入共享的scoped_lock实例...从逻辑上讲会导致数据争用。访问器就像一个或更简单的类std :: shared_ptr和std :: scoped_lock融合在一起-您的结果的指针和它所指向的数据的锁保护。您不想使用来自多个线程的一个全局指针。在您希望拥有该访问权限的范围内本地声明它们(并且您也不必调用.release()

另一个问题是find()和insert()之间的数据竞争。由于找不到任何内容,因此两个或多个线程可以决定必须插入。在这种情况下,第一个线程将插入新元素,而其他线程将返回现有元素,因为如果存在现有元素,则insert()充当find()。问题是您的代码无法解决这个问题。

我可以看到为什么您可能要使用const_accessor进行仔细检查,因为读取锁具有更高的可伸缩性。但是,相反,您可能想将bool insert( const_accessor& result, const value_type& value );与读锁定(const_accessor)和value_type一起使用,而不是仅使用密钥,这将在添加新元素的情况下初始化整个对。