非阻塞线程安全堆栈

时间:2016-03-11 16:55:55

标签: c++ multithreading c++11 c++14

最近我正在阅读Anthony Williams - C ++ Concurrency,我进入了作者建议非阻塞线程安全堆栈实现的章节。在pop()的第一个实现中,据说该方法不是线程安全的。问题是为什么它不是线程安全的?换句话说 - 有人能指出数据竞争的位置吗?

#include <memory>
#include <thread>
#include <iostream>
#include <atomic>

using namespace std;

template <class T>
class lock_free_stack
{
  private:
    struct Node
    {
        std::shared_ptr<T> data_;
        Node *next;


        Node(const T& data): data_(std::make_shared<T>(data)) 
        {
        }

    };
    std::atomic<Node *> head;


    public:
    lock_free_stack() { head.store(nullptr); }

    void push(T const& data)  
    {
        Node* const newNode = new Node(data);
        newNode->next = head.load();
        while(!head.compare_exchange_weak(newNode->next, newNode));
    }

    // The following function is not thread-safe
    std::shared_ptr<T> pop()
    {
        Node* old_head = head.load();

        while (old_head && !head.compare_exchange_weak(old_head, old_head->next)); // Atomically

        unique_ptr<Node> deleter;
        if(old_head)
            deleter.reset(old_head);

        return old_head ? old_head->data_ : std::shared_ptr<T>();
    }

};

1 个答案:

答案 0 :(得分:3)

竞争条件是一个线程可以评估old_head->next,只是在调用unique_ptr的析构函数时(或之后)删除节点old_head指向。