#pragma once #include #include #include using namespace std; template struct Node { T data; //数据 atomic_bool hasData; //是否有数据 }; template class LockFreeQueue { public: LockFreeQueue(int size = 1024) :msg(size) { r_index = 0; w_index = 0; }; bool enqueue(T& value); // 入队列 bool dequeue(T& value); // 出队列 private: vector> msg; // 消息队列 atomic r_index; // 读索引(不考虑溢出情况) atomic w_index; // 写索引(不考虑溢出情况) }; template bool LockFreeQueue::enqueue(T& value) { size_t l_w_index = w_index.load(std::memory_order_relaxed); Node* node = NULL; // CAS比较是否和预期一致,一致则对写索引递增1,不一致则重试 do { //队列是否已满 if (l_w_index >= r_index.load(std::memory_order_relaxed) + msg.size()) { return false; } // 判断是否有数据 size_t index = l_w_index % msg.size(); node = &msg[index]; if (node->hasData.load(std::memory_order_relaxed)) { return false; } } while (!w_index.compare_exchange_weak(l_w_index, l_w_index + 1, std::memory_order_relaxed)); //写数据 node->data = std::move(value);//左值转右值,避免拷贝带来的浪费 node->hasData.store(true); return true; } template bool LockFreeQueue::dequeue(T& value) { size_t l_r_index = r_index.load(std::memory_order_relaxed);; Node* node = NULL; // CAS比较是否和预期一致,一致则对读索引递增1,不一致则重试 do { //队列是否为空 if (l_r_index > w_index.load(std::memory_order_relaxed)) { return false; } // 判断是否有数据 size_t index = l_r_index % msg.size(); node = &msg[index]; if (!node->hasData.load(std::memory_order_relaxed)) { return false; } } while (!r_index.compare_exchange_weak(l_r_index, l_r_index + 1, std::memory_order_relaxed)); //读数据 value = std::move(node->data); node->hasData.store(false); return true; }