以下代码段运行良好:
#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)是原子的还是我应该用其他方法保护检查(关键部分)?
发布于 2022-06-24 07:42:10
您对std::move所做的事情有一个误解。事实上,std::move什么也不做。它只是一种编译时机制,意思是:I不再需要这个命名的值。
这将导致编译器以不同的方式使用该值,比如调用一个移动构造函数/赋值,而不是复制构造函数/赋值。但是std::move本身不会生成任何代码,所以不会受到线程的影响。
您应该问的真正问题是,shared_ptr的移动构造函数是否是线程安全的,答案是:否。
但是,shared_ptr的重点不是共享shared_ptr,而是共享它所指向的内容。不要通过对线程的引用传递shared_ptr,而是通过值传递它,这样每个线程都可以获得它自己的shared_ptr。然后,它可以自由地随意移动,没有问题。
shared_ptr保护它所指向的事物的生命周期。shared_ptr使用的引用计数是线程安全的,但没有其他任何内容。它只以线程安全的方式管理指向对象的生存期,因此只要任何shared_ptr都拥有该对象,它就不会被销毁。
https://stackoverflow.com/questions/72737316
复制相似问题