C++线程安全双向链表

Posted

技术标签:

【中文标题】C++线程安全双向链表【英文标题】:C++ thread safe doubly linked list 【发布时间】:2010-09-13 08:34:31 【问题描述】:

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

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

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

【问题讨论】:

你能写出你真正需要的结构操作吗?也许您并不真的需要双链表,而其他结构也可以工作? 你想要多线程安全?您想从任意线程写入任意位置? 您要求添加和删除的速度有多快?乍一看,它似乎是一个哈希表可能对你有用。可扩展的线程安全哈希表很常见 - 只需搜索一些即可。 这个数据结构在任何时候都可能包含相当多的项目,所以它应该很快。这是一个服务器应用程序,有许多客户端。 删除项目以进行处理。 【参考方案1】:

可能有,但我认为这是 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.

这里,因为锁的粒度比较大,所以可以保证跨写算法的一致性。

【讨论】:

【参考方案2】:

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

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

注意:虽然接口和性能特征看起来像一个双链表,但在内部,这些结构非常复杂,基于哈希表或其他结构。没有什么东西可以在内部建立一个双链表,并且同时是无锁的。我不记得看过证明,但我认为这是不可能的。


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

【讨论】:

是的! InterlockedSLists 非常快,并且已经内置到操作系统中【参考方案3】:

http://www.boost.org/doc/libs/1_41_0/doc/html/boost/interprocess/message_queue.html 会起作用吗?

【讨论】:

【参考方案4】:

关于使用汇编/编译器内部函数编写无锁队列来执行原子操作的论文很多,但要让它工作起来真的很困难。

所以如果你可以使用锁,也许可以使用这样的东西:Concurrent FIFO Queue with Boost

【讨论】:

以上是关于C++线程安全双向链表的主要内容,如果未能解决你的问题,请参考以下文章

使用线程安全型双向链表实现简单 LRU Cache 模拟

C++并发编程:线程安全链表

C++并发编程:线程安全链表

C++并发编程:线程安全链表

其他类型的链表总结

C++并发编程----利用锁实现线程安全的数据结构(《C++ Concurrency in Action》 读书笔记)