我正在编写的应用程序需要上面的数据结构。我想知道是否有一个库已经实现了它,或者我是否必须自己编写它?
如果没有必要,我真的不想重新发明轮子。
我需要这个结构能够使用多个线程添加和删除项目,而不必在执行此操作时锁定整个结构。
答案 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