Anne Quinn
Anne Quinn

Reputation: 13040

Does C++ offer a thread-safe reference counter?

Is there a thread-safe reference counter class in the standard C++ library, (or as an extension in Visual Studio), or would I need to write this kind of object from scratch?

I'm hoping for an object that purely performs reference counting as shared_ptr might, with the exception that it does so across multiple threads accurately, and without managing anything. shared_ptr and it's cousin structures are nice because they define all the copy constructors and assignment operators you'd need, which ... are the most error prone part of C++ to me; C++ Constructors are to C++ what the Kick-off is to American Football.

struct Fun {

    // this member behaves in a way I appreciate, save for 2 short-comings:
    // - needless allocation event (minor)
    // - ref counting is only estimate if shared across threads (major)
    std::shared_ptr<int> smartPtr {new int};  

    // this is the hypothetical object that I'm searching for
    // + allocates only a control block for the ref count
    // + refCount.unique() respects reality when refs exist across many threads
    //   I can always count on this being the last reference
    std::object_of_desire refCount;

    // no explicit copy constructors or assignment operators necessary
    // + both members of this class provide this paperwork for me, 
    //   so I can careless toss this Fun object around and it'll move
    //   as one would expect, making only shallow copies/moves and ref counting
    Fun(); 

    ~Fun(){
        if(refCount.unique()){
             smart_assert("I swear refCount truly is unique, on pain of death");
        }
    }
}

Upvotes: 4

Views: 1078

Answers (1)

Caleth
Caleth

Reputation: 63162

The warnings about thread safety w.r.t. std::shared_ptr are

  • If you have multiple threads that can access the same pointer object, then you can have a data race if one of those threads modifies the pointer. If each thread has it's own instance, pointing to the same shared state, there are no data races on the shared state.
  • The final modification of the pointed-to object on a thread does not inter-thread happens before another thread observing a use_count of 1. If nothing is modifying the pointed-to object, there are no data races on the pointed-to object.

Here's your desired type

class ref_count {
public:
    bool unique() const { return ptr.use_count() == 1; }
private:
    struct empty {};
    std::shared_ptr<empty> ptr = std::make_shared<empty>();
};

Upvotes: 2

Related Questions