是否存在乐观的无锁FIFO队列实现?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否存在乐观的无锁FIFO队列实现?相关的知识,希望对你有一定的参考价值。

是否有任何C ++实现(源代码)“optmistic approach to lock-free FIFO queues" algorithm

答案

qazxsw poi在Dobbs Journal博士的有效并发专栏中介绍了这样一个队列。

Herb Sutter

另一答案

我想总结一下greyfade给出的答案,它基于Writing Lock-Free Code: A Corrected Queue(文章的最后部分),优化的代码将是(根据我的命名和编码惯例进行一些修改):

http://www.drdobbs.com/high-performance-computing/212201163

`

另一个问题是你如何定义CACHE_LINE_SIZE?它的CPU有所不同吗?

另一答案

这是我实现的无锁FIFO。

确保T的每个项目是64字节的倍数(Intel CPU中的缓存行大小),以避免错误共享。

这段代码用gcc / mingw编译,应该用clang编译。它针对64位进行了优化,因此要使其在32位上运行需要进行一些重构。

template <typename T> class LFQueue { private: struct LFQNode { LFQNode( T* val ) : value(val), next(nullptr) { } T* value; AtomicPtr<LFQNode> next; char pad[CACHE_LINE_SIZE - sizeof(T*) - sizeof(AtomicPtr<LFQNode>)]; }; char pad0[CACHE_LINE_SIZE]; LFQNode* first; // for one consumer at a time char pad1[CACHE_LINE_SIZE - sizeof(LFQNode*)]; InterlockedFlag consumerLock; // shared among consumers char pad2[CACHE_LINE_SIZE - sizeof(InterlockedFlag)]; LFQNode* last; // for one producer at a time char pad3[CACHE_LINE_SIZE - sizeof(LFQNode*)]; InterlockedFlag producerLock; // shared among producers char pad4[CACHE_LINE_SIZE - sizeof(InterlockedFlag)]; public: LFQueue() { first = last = new LFQNode( nullptr ); // no more divider producerLock = consumerLock = false; } ~LFQueue() { while( first != nullptr ) { LFQNode* tmp = first; first = tmp->next; delete tmp; } } bool pop( T& result ) { while( consumerLock.set(true) ) { } // acquire exclusivity if( first->next != nullptr ) { // if queue is nonempty LFQNode* oldFirst = first; first = first->next; T* value = first->value; // take it out first->value = nullptr; // of the Node consumerLock = false; // release exclusivity result = *value; // now copy it back delete value; // and clean up delete oldFirst; // both allocations return true; // and report success } consumerLock = false; // release exclusivity return false; // queue was empty } bool push( const T& t ) { LFQNode* tmp = new LFQNode( t ); // do work off to the side while( producerLock.set(true) ) { } // acquire exclusivity last->next = tmp; // A: publish the new item last = tmp; // B: not "last->next" producerLock = false; // release exclusivity return true; } };

https://github.com/vovoid/vsxu/blob/master/engine/include/vsx_fifo.h

发件人:

vsx_fifo<my_struct, 512> my_fifo;

接收器:

my_struct my_struct_inst;
... fill it out ...
while (!my_fifo.produce(my_struct_inst)) {}
另一答案

如果您正在寻找一个良好的无锁队列实现,Microsoft Visual Studio 2010和英特尔的线程构建块都包含一个很好的LF队列,类似于本文。

my_struct my_struct_recv; while(my_fifo.consume(my_struct_recv)) { ...do stuff... }

另一答案

这个Here's a link to the one in VC 2010怎么样?

这是跨平台,无限排队的线程安全队列,已经过多deq,多enq-deq和多enq的测试。保证内存安全。

例如

lfqueue

以上是关于是否存在乐观的无锁FIFO队列实现?的主要内容,如果未能解决你的问题,请参考以下文章

dpdk无锁队列rte_ring实现分析

dpdk无锁队列rte_ring实现分析

乐观锁是基于比较的无锁并发控制机制

linux内核无锁缓冲队列kfifo原理

多线程编程之无锁队列

在 Folly 的无锁 SPSC 队列中使用 std::memory_order_consume