以下是一个简单的无锁消息队列的 C++ 实现示例,使用了 CAS(Compare-And-Swap)操作来实现无锁同步。这个示例假设消息队列是单生产者单消费者的情况。
#include <atomic>
#include <memory>
template<typename T>
class LockFreeQueue {
private:
struct Node {
std::shared_ptr<T> data;
Node* next;
Node() : next(nullptr) {}
};
std::atomic<Node*> head;
std::atomic<Node*> tail;
public:
LockFreeQueue() : head(new Node), tail(head.load()) {}
LockFreeQueue(const LockFreeQueue& other) = delete;
LockFreeQueue& operator=(const LockFreeQueue& other) = delete;
~LockFreeQueue() {
while (Node* const old_head = head.load()) {
head.store(old_head->next);
delete old_head;
}
}
void push(T new_value) {
std::shared_ptr<T> new_data(std::make_shared<T>(std::move(new_value)));
Node* const new_node = new Node;
Node* old_tail = tail.load();
while (true) {
if (old_tail->next == nullptr) {
if (tail.compare_exchange_weak(old_tail->next, new_node)) {
break;
}
} else {
tail.compare_exchange_weak(old_tail, old_tail->next);
}
}
old_tail->data.swap(new_data);
}
std::shared_ptr<T> pop() {
Node* old_head = head.load();
while (true) {
if (old_head == nullptr) {
return nullptr;
}
Node* const new_head = old_head->next;
if (head.compare_exchange_weak(old_head, new_head)) {
std::shared_ptr<T> res;
res.swap(old_head->data);
delete old_head;
return res;
}
}
}
};
这个实现使用两个指针 head
和 tail
分别指向队列的头部和尾部。push
操作通过 CAS 操作来向队列尾部添加新节点,而 pop
操作则通过 CAS 操作从队列头部移除节点。由于 CAS 操作是原子的,因此这个实现是线程安全的,并且不需要使用显式的锁。