本文转自https://www.codeproject.com/Articles/43510/Lock-Free-Single-Producer-Single-Consumer-Circular#heading_memory_model一个环形无锁模型
需要自定义一个数组作为队列,实际大小比给定大小多一,因为判断是否满的条件是tail+1==head?判断是否为空的条件是tail==head?
template‹typename Element, size_t Size›
class CircularFifo{
public:
enum { Capacity = Size+1 };
CircularFifo() : _tail(0), _head(0){}
virtual ~CircularFifo() {}
bool push(const Element& item);
bool pop(Element& item);
bool wasEmpty() const;
bool wasFull() const;
bool isLockFree() const;
private:
size_t increment(size_t idx) const;
std::atomic‹size_t› _tail;
Element _array[Capacity];
std::atomic‹size_t› _head;
};
生产这加入item 需要判断是否为满
/* Producer only: updates tail index after setting the element in place */
bool push(Element& item_)
{
auto current_tail = _tail.load();
auto next_tail = increment(current_tail);
if(next_tail != _head.load())
{
_array[current_tail] = item;
_tail.store(next_tail);
return true;
}
return false; // full queue
}
消费者消费 需要判断是否为空
/* Consumer only: updates head index after retrieving the element */
bool pop(Element& item)
{
const auto current_head = _head.load();
if(current_head == _tail.load())
return false; // empty queue
item = _array[current_head];
_head.store(increment(current_head));
return true;
}
生产者读head,写tail,防止脏读的情况出现,可以使用atomicInteget来保证head和tail读写的一致性