C ++线程安全的双向链表

时间:2010-09-13 08:34:31

标签: c++ windows data-structures

我正在编写的应用程序需要上面的数据结构。我想知道是否有一个库已经实现了它,或者我是否必须自己编写它?

如果没有必要,我真的不想重新发明轮子。

我需要这个结构能够使用多个线程添加和删除项目,而不必在执行此操作时锁定整个结构。

4 个答案:

答案 0 :(得分:5)

可能有,但我认为这是Java早期的经验教训之一 - 数据同步性通常不是容器的成员函数级别,而是上面的一步。您应该在访问非线程安全列表之前使用同步对象。

考虑:

ThreadSafeQueue tsq;
tsq.push_back(...); // add lots of data

...

// Find the first element that returns true for search_criteria(elem);
auto iter = tsq.find_if(search_criteria); 
// (1)                                  
if(iter != tsq.end()) // (2)
{
    tsq.erase(iter);
}

在这个线程安全的队列中,仍有两个“间隙”,其中队列可以被另一个线程更改。实际上,这些更改可能会使您的迭代器失效。现在比较:

Queue q;
q.push_back(...); // add lots of data

...

// Create some lock around a pre-existing mutex.
Lock lock(q_mutex);
// Find the first element that returns true for search_criteria(elem);
auto iter = q.find_if(search_criteria); 

if(iter != q.end())
{
    q.erase(iter);
}
// lock unlocks as it goes out of scope.

这里,因为锁具有更大的粒度,所以可以确保整个书面算法的一致性。

答案 1 :(得分:2)

链接到相关研究:Is a lock (wait) free doubly linked list possible?

由于您没有要求无锁容器,因此我并未将其标记为完全重复。

注意:虽然接口和性能特征看起来像双链表,但在内部这些结构非常复杂,基于哈希表或其他结构。内部没有任何双链表可以同时锁定。我不记得见过证据,但我认为这是不可能的。


根据您的其他信息,我认为您根本不需要双重链接列表。您可以使用Windows API single linked list instead。要添加使用InterlockedPushEntrySList,要删除处理使用InterlockedPopEntrySList。

答案 2 :(得分:0)

答案 3 :(得分:0)

有大量关于使用汇编/编译器内部函数编写无锁队列以执行原子操作的论文,但实际上很难让它工作。

因此,如果您可以使用锁,可以使用以下内容:Concurrent FIFO Queue with Boost