使用C++ 模板实现的单生产者与单消费者的无锁队列
一个生产者与一个消费者的通信时,使用此无锁队列,无需任何锁即可保证线程安全
#include <vector>
template<typename T>
class ring {
public:
ring(int size):v(size+1),size(size+1) {
};
ring(const ring& r) = delete;
ring& operator = (const ring& r) = delete;
ring& operator = (ring&& r) = delete;
ring(ring&& r) = delete;
int ring_size() const{
return size-1;
}
int ring_used() const{
return (tail - head + size) % size;
}
int ring_free() const{
return size - 1 - ring_used();
}
bool ring_empty() const {
return ring_used() == 0;
}
bool ring_full() const {
return ring_free() == 0;
}
bool ring_enqueue(typename T data) {
if (ring_full()) {
return false;
}
v[tail] = data;
#ifdef __GNUC__
__sync_synchronize();
#endif
tail = (tail + 1) % size;
return true;
}
bool ring_dequeue(typename T & data) {
if (ring_empty()) {
return false;
}
data = v[head];
#ifdef __GNUC__
__sync_synchronize();
#endif
head = (head + 1) % size;
return true;
}
private:
int head{ 0 };
int tail{ 0 };
std::vector<T> v;
int size;
};
测试代码
#include <iostream>
#include <vector>
#include <thread>
int f(ring<int>* r) {
int i = -1,j=-1;
while (1) {
if (r->ring_dequeue(i)) {
if (j != i - 1) {
cout << "error-----------------------------------" << endl;
}
cout << i << endl;
}
}
}
int main() {
ring<int> r(10);
thread t(f, &r);
for (int i = 0; i < 1001; ) {
if (r.ring_enqueue(i)) {
i++;
}
}
t.join();
return 0;
}
主线程main作为生产者,函数f线程作为消费者,将从队列中获取到的数据打印在屏幕上。