Search code examples
c++multithreadingconcurrencyshared-ptr

std::shared_ptr concurrent access sanity check


I'm trying to make sure I correctly understand the semantics of std::shared_ptr, where:

  • Modifications to the underlying shared reference counter (std::_Sp_counted_base in the stdc++ implementation that ships with GCC) are thread-safe.
  • Access to a given instance of an std::shared_ptr is not thread-safe.

With that in mind, consider the following snippet:

struct Data {
    std::shared_pointer<X> x;
    std::shared_pointer<Y> y;
};

void SomeThread1 (Data d) {
    std::shared_pointer<X> localxptr = d.x;
    ...
}

void SomeThread2 (std::shared_ptr<Data> d) {
    std::shared_pointer<X> localxptr = d.x;
    ...
}

Assuming SomeThread[12] are their own threads, and whoever created them passed the appropriate parameters, am I correct in believing that:

  • SomeThread1 is safe: Since d is a copied Data, d.x is therefore a unique instance of the shared_ptr<X> member and can thus be copied again safely into localxptr.
  • SomeThread2 is not safe: Since d is a pointer to a Data, d.x is therefore the same shared_ptr<X> instance that the calling thread has and thus cannot be copied safely into localxptr, which risks both the new thread and the calling thread (and anybody else) accessing that same shared_ptr<X> instance.

Is my assessment correct?

Seems obvious, but I just want a sanity check because I've been staring at a lot of code for too long lately.


Solution

  • The other question you linked seems to provide the answer: it depends on what other threads may be doing.

    A shared_ptr is not thread safe if it is used in a non-const way. However, you are only passing it in to the copy constructor (9), which accepts it as a const reference. If all other threads are accessing it in the same way (none of them attempt to modify it), this is safe as written.