无锁消息队列C++实现

141 阅读1分钟

以下是一个简单的无锁消息队列的 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;
            }
        }
    }
};

这个实现使用两个指针 headtail 分别指向队列的头部和尾部。push 操作通过 CAS 操作来向队列尾部添加新节点,而 pop 操作则通过 CAS 操作从队列头部移除节点。由于 CAS 操作是原子的,因此这个实现是线程安全的,并且不需要使用显式的锁。