【发布时间】:2021-08-27 22:10:01
【问题描述】:
如果我有一个 shared_ptr 复制到 std::thread,分离线程,然后我销毁 shared_ptr 的所有其他副本,我可以期望分离的线程继续拥有 shared_ptr 的活动副本吗? 例如,如果我有:
{
std::shared_ptr<Foo> my_foo = std::make_shared<Foo>();
std::thread soon_detached([my_foo = my_foo]() {my_foo->bar()});
soon_detached.detach();
}
我可以相信bar() 在这种情况下调用是“安全的”吗(因为即使my_foo 的初始副本很长,它也不会尝试在正在被破坏/被破坏的 Foo 上调用 bar超出范围?
【问题讨论】:
-
由于您已经按值捕获,因此您增加了引用计数器,该计数器将在 lambda 范围结束时再次减少。
-
为什么你认为分离线程可以在这里有所作为?
-
关于分离线程的常见警告:真的,真的确定这是你想要的行为。您已经放弃了对线程的所有控制权,而这通常以失败告终。如果您已经采取措施来缓解这种情况,那就太好了。如果没有,请知道可能需要采取一些步骤。
-
@AryanSefidi 在我的理解中,当您创建线程对象时,lambda 对象本身会被复制(实际上是移动)。然而,它将属于底层线程,而不是线程对象本身;因此,销毁线程对象不会破坏 lambda 对象,也不会破坏它包含的 shared_ptr,也不会分离线程。
-
示例程序来演示。这有点复杂,完全删除 shared_ptr 可能会有所帮助,因此您可以更清楚地看到
foo2对象的生命周期:godbolt.org/z/1GrsjnxY4
标签: c++ multithreading memory shared-ptr smart-pointers