liveBook · Manning

Std::experimental::atomic_shared_ptr

As explained in C++ Concurrency in Action, Second Edition

`std::experimental::atomic_shared_ptr` is a C++ Concurrency TS type that provides atomic operations on shared-pointer ownership.

std::experimental::atomic_shared_ptr<T> provides atomic operations on shared-pointer ownership. It supports load, store, exchange, and compare-exchange, and requires the <experimental/atomic> header. The type may or may not be lock-free on a given implementation; check with is_lock_free(). section 5.2.7 section 7.2.4

Use the dedicated type to:

  • Make shared-pointer accesses atomic through the type’s member operations, rather than relying on consistently using atomic free functions with a plain std::shared_ptr. section 5.2.7 section 7.2.4
  • Manage reference counting correctly while using atomic operations; if the implementation is not lock-free, this type does not itself provide lock-free operation. section 7.2.4
Listing 7.10. Stack implementation using std::experimental::atomic_shared_ptr<>
template<typename T>
class lock_free_stack
{
private:
    struct node
    {
        std::shared_ptr<T> data;
        std::experimental::atomic_shared_ptr<node> next;
        node(T const& data_):
            data(std::make_shared<T>(data_))
        {}
    };
    std::experimental::atomic_shared_ptr<node> head;
public:
    void push(T const& data)
    {
        std::shared_ptr<node> const new_node=std::make_shared<node>(data);
        new_node->next=head.load();
        while(!head.compare_exchange_weak(new_node->next,new_node));
    }
    std::shared_ptr<T> pop()
    {
        std::shared_ptr<node> old_head=head.load();
        while(old_head && !head.compare_exchange_weak(
                  old_head,old_head->next.load()));
        if(old_head) {
            old_head->next=std::shared_ptr<node>();
            return old_head->data;
        }
        return std::shared_ptr<T>();
    }
    ~lock_free_stack(){
        while(pop());
    }
};

The stack stores its head and each node’s next pointer as atomic_shared_ptr values, using member loads and compare-exchange operations to update them. section 7.2.4

How C++ Concurrency in Action, Second Edition covers it

How deep it goes
Explains core operations and lock-free checks, then demonstrates their use in a stack implementation.
Examples
Uses a stack whose head and node links are atomic_shared_ptr values.
What you can do after
Apply it via load, store, exchange, and compare-exchange to make shared-pointer accesses atomic.
How it connects
Connects shared_ptr, atomic operations, reference counting, and lock-free stacks.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C++ Concurrency in Action, Second Edition. The section links point to the parts of the book it draws on.