线程分配 shared_ptr nullptr 是否安全?

Is thread safe to assign a shared_ptr nullptr?

假设有一个shared_ptr:

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

在工作线程中:

myPtr = nullptr;

在主线程中:

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

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

不,这不是线程安全的。

A shared_ptr 在线程安全方面表现得像内置类型:并发访问不同的对象是可以的,而并发访问 same 对象则不行.也就是说,多个线程可以随心所欲地操纵指向同一个对象的不同shared_ptr。但是一旦您共享 shared_ptr 本身,事情就会变得危险。

使用 atomic non-member functions 从多个线程同时访问同一个 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) [...]

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