分配 shared_ptr nullptr 的线程安全吗?

Zac*_*ach 3 thread-safety shared-ptr c++11

假设有一个shared_ptr:

std::shared_ptr<MyClass> myPtr = std::make_shared(new MyClass());
Run Code Online (Sandbox Code Playgroud)

在工作线程中:

myPtr = nullptr;
Run Code Online (Sandbox Code Playgroud)

在主线程中:

if( myPtr != nullptr )
{
    // do something
}
Run Code Online (Sandbox Code Playgroud)

上面的代码线程安全吗?还是主线程可以立即看到新值?

Com*_*sMS 5

不,这不是线程安全的。

Ashared_ptr在线程安全方面的行为类似于内置类型:并发访问不同的对象很好,而并发访问同一对象则不然。也就是说,多个线程可以随意操作shared_ptr指向同一对象的不同s。但是一旦你分享它shared_ptr本身,事情就会变得危险。

使用原子非成员函数shared_ptr从多个线程并发访问同一个对象:

// 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) [...]
Run Code Online (Sandbox Code Playgroud)

请注意,这仅在所有访问shared_ptronly 的线程都通过原子函数进行时才有效。否则,您可能仍会遇到数据竞争。为了使源代码中的这一限制更加明确,C++20 引入了针对std::atomic<std::shared_ptr>旧的自由函数的特化并弃用了旧的自由函数。