是std::move的shared_ptr线程安全吗?



下面的代码片段运行正常:

#include <memory>
#include <cassert>
int main()
{
auto ptr1 = std::make_shared<int>(10);
assert(ptr1.use_count() == 1);
auto ptr2 = std::move(ptr1);
assert(ptr1 == nullptr);
auto ptr3 = static_cast<std::shared_ptr<int>&&>(ptr2);
assert(ptr2 == nullptr);
assert(ptr3.use_count() == 1);
}

看起来std::move做了几个操作,其中一个是重置移动的共享指针,所以这个线程安全吗?例如,如果我有这样的内容:

void ThreadLogic()
{
if (sharedPtr != nullptr)
{
DoSomething(std::move(sharedPtr));
}
else
{
DoSomethingElse();
}
}

std::move(sharedPtr)原子还是我应该用其他方法保护检查(临界区)?

你对std::move的作用有误解。事实上,std::move没有任何作用。它只是一个编译时机制,其含义是:我不再需要这个命名值.

这会导致编译器以不同的方式使用该值,比如调用移动构造函数/赋值函数,而不是调用复制构造函数/赋值函数。但是std::move本身不生成代码,所以不会受到线程的影响。

你应该问的真正问题是shared_ptr的move构造函数是否线程安全,答案是:否。

但是shared_ptr的重点不是分享shared_ptr,而是分享它所指向的东西。不要将shared_ptr通过引用传递给线程,而是通过值传递,这样每个线程都可以获得自己的shared_ptr。然后,它可以自由地移动,没有问题。

shared_ptr保护它所指向的对象的生命周期。shared_ptr使用的引用计数是线程安全的,仅此而已。它只以线程安全的方式管理被指向对象的生命周期,因此只要任何shared_ptr持有该对象,它就不会被销毁。

最新更新