【问题标题】:Does a detached thread keep its captured shared_ptr alive?分离的线程是否保持其捕获的 shared_ptr 活着?
【发布时间】: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


【解决方案1】:

分离的线程是否保持其捕获的 shared_ptr 处于活动状态?

是的。只要线程正在执行,lambda - 因此也是 lambda 的捕获 - 将保持活动状态。这同样适用于传递给std::threadargs

我们正在删除作用域末尾的 std::thread 句柄

std::thread 对象不包含函子。它将需要存储在动态内存中。执行线程的生命周期与 std::thread 包装器的生命周期是分开的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 2014-06-19
    • 2018-04-28
    • 1970-01-01
    相关资源
    最近更新 更多