A minimalistic kind of read-copy-update class This is a very simple read-copy-update (RCU)-inspired synchronization class:

#include &lt;atomic&gt;


template&lt;typename T&gt;
class RCU
{
private:

    std::atomic&lt;T*&gt;  curr;
    std::atomic&lt;T*&gt;  prev;
    std::atomic&lt;int&gt; readers;

public:

    RCU()
    : curr   (new T),
      prev   (nullptr),
      readers(0)
    {

    }

    ~RCU()
    {
        delete curr;
        delete prev;
    }

    void lock()
    {
        readers++;
    }

    void unlock()
    {
        readers--;
    }

    T* get()
    {
        return curr.load();
    }

    T* clone()
    {
        return new T(*curr.load());
    }

    bool swap(T* t)
    {
        /* If prev is full, a swap is still pending. Clean up memory and
        abort the operation. */

        if (prev.load() != nullptr)
        {
            delete t;
            return false;
        }

        /* Store the current pointer into prev. Readers might still be reading
        through the pointer. */

        prev.store(curr);

        /* Curr contains the new proposed value. No one is reading from this
        right now. */

        curr.store(t);

        /* Spin until there are no more readers to *prev. When so, free the
        memory it points to and say goodbye. */

        while (readers.load() &gt; 0);

        T* old = prev.load();
        prev.store(nullptr);
        delete old;

        return true;
    }
};


The idea is to have many reader threads that repeatedly read from some shared data, while a writer thread that rarely updates it. The writer thread takes care of cleaning up the memory when no readers are reading. Readers are "tracked" through the lock() and unlock() methods. The RCU-like class should synchronize the threads in a lock-free way. 

Usage:

struct Data
{
    int x;
    int y;
    int z;
};


RCU&lt;Data&gt; rcu;


void writer_thread()  // the writer rarely runs
{
    while (true)
    {
        Data* data = rcu.clone(); 
        // modify data as needed
        data-&gt;x++; 
        data-&gt;y++;
        data-&gt;z++;
        rcu.swap(data); // Checking the return value might be useful 
    }
}


void reader_thread() 
{
    while (true)
    {
        rcu.lock();
        std::cout &lt;&lt; rcu.get()-&gt;x &lt;&lt; "\n"; // read from data
        rcu.unlock();
    }
}


Questions: does it make sense? Is it really thread-safe? Can a thread slip through the cracks somewhere, somehow?
Serious issues with this:

Memory Management.
Not using RAII to lock/unlock

Memory Management
Don't pass pointers it does not indicate owners. Always wrap pointers in a smart pointer. Have a look at std::unique_ptr.
But for types like Data there is no need to use pointers. Simply use Data as the object type (not Data*).
RAII
Look up the concept of RAII.
A good example is std::lock_guard https://en.cppreference.com/w/cpp/thread/lock_guard This shows you how to use RAII to automate the processes of lock/unlock so it is exception safe.