是否存在乐观的无锁FIFO队列实现?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否存在乐观的无锁FIFO队列实现?相关的知识,希望对你有一定的参考价值。
是否有任何C ++实现(源代码)“optmistic approach to lock-free FIFO queues" algorithm?
qazxsw poi在Dobbs Journal博士的有效并发专栏中介绍了这样一个队列。
我想总结一下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队列实现?的主要内容,如果未能解决你的问题,请参考以下文章