jeudi 28 mai 2015

When we implement lock-free data structures, why do we need to manage memory?

When we implement lock-free data structures, why do we need to manage memory? Consider the following stack example, why does the "delete old_head" statement in the pop function , as the book say, cause problems to other threads? I don't see chances that "dereferencing a dangling pointer" can happen, and I run the code several times, not getting any error.

template<typename T>
class lock_free_stack
{
private:
    struct node
    {
        std::shared_ptr<T> data;
        node* next;
        node(T const& data_) :
            data(std::make_shared<T>(data_))
        {}
    };
    std::atomic<node*> head;

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

    std::shared_ptr<T> pop()
    {
        node* old_head = head.load();
        while (old_head &&
            !head.compare_exchange_weak(old_head, old_head->next));
        auto res = old_head ? old_head->data : nullptr;
        delete old_head;
        return res;
    }
};

Aucun commentaire:

Enregistrer un commentaire