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

问题描述 投票:10回答:5

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

c++ multithreading queue lock-free fifo
5个回答
11
投票

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

Herb Sutter


4
投票

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

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

`

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


1
投票

这是我实现的无锁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)) {}

0
投票

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

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


0
投票

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

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

例如

lfqueue
© www.soinside.com 2019 - 2024. All rights reserved.