线程分配 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>
的特化并弃用了旧的自由函数。
假设有一个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>
的特化并弃用了旧的自由函数。