C++无锁编程-无锁栈的设计与实现

无锁栈实现原理

本文是用过C++11标准下的原子变量atomic的CAS操作compare_exchange_weak,来实现无锁栈(Lock-free Stack)。

  • 通过compare_exchange_weak方法,来实现栈顶元素添加操作的原子性。
  • 栈内元素都会由Node数据结构封装,可以规避CAS操作的ABA问题。

无锁栈实现编码

#ifndef LOCK_FREE_STACK_HPP
#define LOCK_FREE_STACK_HPP

#include 

template
class LockFreeStack {
public:
    struct Node {
        Node() : data(nullptr), pre(nullptr) {}
        void reset() { data = nullptr; pre = nullptr;}

        T *data;
        Node* pre;
    };

    LockFreeStack() : count(0), back(nullptr) {}
    ~LockFreeStack() { clear(); }

    void push(const T* data) {
        Node* node = alloc();
        node->data = const_cast(data);
        for (;;) {
            node->pre = back;
            if (back.compare_exchange_weak(node->pre, node, std::memory_order_seq_cst) ) {
                break;
            } else {
                continue;
            }
        }
        ++count;
    }

    T* pop() {
        for (;;) {
            Node* back_node = back;
            if (nullptr == back_node) { return nullptr; }
            Node* second_node = back_node->pre;
            if(!back.compare_exchange_weak(back_node, second_node, std::memory_order_seq_cst)) {
                continue;
            } else {
                --count;
                T* data = back_node->data;
                recycle(back_node);
                return data;
            }
        }
    }
    bool empty() { return (bool)count; }
    int64_t size() { return count; }
    void clear() { while (nullptr != pop()) {}; }

private:
    Node *alloc() { return (new Node()); }
    void recycle(Node *node) { delete node; }

    std::atomic count;
    std::atomic back;
};
#endif

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注