Zach
Zach

Reputation: 5895

Is thread safe to assign a shared_ptr nullptr?

Suppose there is a shared_ptr:

std::shared_ptr<MyClass> myPtr = std::make_shared(new MyClass());

In worker thread:

myPtr = nullptr;

In main thread:

if( myPtr != nullptr )
{
    // do something
}

Is the code above thread safe? Or can the main thread see the new value immediately?

Upvotes: 3

Views: 988

Answers (1)

ComicSansMS
ComicSansMS

Reputation: 54777

No, this is not thread-safe.

A shared_ptr behaves like a built-in type regarding thread-safety: Concurrent access to distinct objects is fine, while concurrent access to the same object is not. That is, multiple threads may manipulate different shared_ptrs pointing to the same object as they like. But as soon as you share the shared_ptr itself, things get dangerous.

Use the atomic non-member functions to access the same shared_ptr object concurrently from multiple threads:

// atomically set myPtr to nullptr
std::atomic_store(&myPtr, std::shared_ptr<MyClass>{});
[...]


// atomically check the current value of myPtr
if(std::atomic_load(&myPtr) != nullptr) [...]

Note that this only works if all threads accessing the shared_ptr only do so through the atomic functions. Otherwise you might still end up with a data race. To make this restriction more explicit in the source code, C++20 introduced specializations for std::atomic<std::shared_ptr> and deprecated the old free functions.

Upvotes: 5

Related Questions