C++ 并发无锁队列的原理与实现
一般无锁队列的情况分为两种,第一种是单个消费者与单个生产者,第二种是多个消费者或者多个生产着的情况。
一.单个消费者与单个生产者的情况
这种情况下可以用环形队列RingBuffer来实现无锁队列,比如dpdk和kfifo的无锁队列就是用环形队列实现的,kfifo里面的入队和出队的处理很巧妙,大家可以去看看。
DPDK:https://blog.csdn.net/s2603898260/article/details/109565922
KFIFO:https://blog.csdn.net/weixin_30426957/article/details/96164037
用数组模拟环形队列举个简单的例子:
#include <stdio.h>
#include <thread>
#include <unistd.h>
#include <iostream>
using namespace std;
#define RING_QUEUE_SIZE 10
template <class T>
class RingBuffer {
public:
RingBuffer(int size): m_size(size),m_head(0), m_tail(0) {
m_buf = new T[size];
}
~RingBuffer() {
delete [] m_buf;
m_buf = NULL;
}
inline bool isEmpty() const {
return m_head == m_tail;
}
inline bool isFull() const {
return m_tail == (m_head + 1) % m_size; //取模是为了考虑队列尾的特殊情况
}
bool push(const T& value) { //以实例的方式传值
if(isFull()) {
return false;
}
m_buf[m_head] = value;
m_head = (m_head + 1) % m_size;
return true;
}
bool push(const T* value) { //以指针的方式传值
if(isFull()) {
return false;
}
m_buf[m_head] = *value;
m_head = (m_head + 1) % m_size;
return true;
}
inline bool pop(T& value)
{
if(isEmpty()) {
return false;
}
value = m_buf[m_tail];
m_tail = (m_tail + 1) % m_size;
return true;
}
inline unsigned int head()const {
return m_head;
}
inline unsigned int tail()const {
return m_tail;
}
inline unsigned int size()const {
return m_size;
}
private: