lock-free circle queue实现

本文转自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读写的一致性

你可能感兴趣的:(lock-free circle queue实现)