我什么时候应该使用 std::thread::detach?

新手上路,请多包涵

有时我必须使用 std::thread 来加速我的应用程序。我也知道 join() 等到一个线程完成。这很容易理解,但是调用 detach() 和不调用有什么区别呢?

我认为没有 detach() ,线程的方法将独立使用线程工作。

不分离:

 void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called without detach");
    });

    //some code here
}

使用分离调用:

 void Someclass::Somefunction() {
    //...

    std::thread t([ ] {
        printf("thread called with detach");
    });

    t.detach();

    //some code here
}

原文由 Jinbom Heo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

std::thread std::terminate 析构函数中,如果:

  • 线程未加入(与 t.join()
  • 并且也没有分离(使用 t.detach()

因此,在执行流到达析构函数之前,您应该始终使用 joindetach 一个线程。


当程序终止时(即 main 返回),不会等待在后台执行的剩余分离线程;相反,它们的执行被暂停并且它们的线程本地对象被破坏。

至关重要的是,这意味着 _这些线程的堆栈不会展开_,因此某些析构函数不会被执行。根据这些析构函数应该执行的操作,这可能与程序崩溃或被杀死一样糟糕。希望操作系统会释放对文件等的锁定……但您可能已经损坏了共享内存、半写文件等。


那么,您应该使用 join 还是 detach

  • 使用 join
  • 除非你需要更大的灵活性并且愿意提供一个同步机制来 自己 等待线程完成,在这种情况下你可以使用 detach

原文由 Matthieu M. 发布,翻译遵循 CC BY-SA 3.0 许可协议

此答案旨在回答标题中的问题,而不是解释 joindetach 之间的区别。那么什么时候应该使用 std::thread::detach

在正确维护的 C++ 代码 std::thread::detach 根本不应该使用。程序员必须确保所有创建的线程优雅地退出释放所有获取的资源并执行其他必要的清理操作。这意味着通过调用 detach 放弃线程所有权不是一个选项,因此 join 应该在所有场景中使用。

然而,一些应用程序依赖于旧的且通常设计和支持不佳的 API,这些 API 可能包含无限期的阻塞函数。将这些函数的调用移动到专用线程中以避免阻塞其他东西是一种常见的做法。没有办法让这样的线程优雅地退出,所以使用 join 只会导致主线程阻塞。在这种情况下,使用 detach 将是一个不那么邪恶的替代方案,例如,分配 thread 具有动态存储持续时间的对象,然后故意泄漏它。

 #include <LegacyApi.hpp>
#include <thread>

auto LegacyApiThreadEntry(void)
{
    auto result{NastyBlockingFunction()};
    // do something...
}

int main()
{
    ::std::thread legacy_api_thread{&LegacyApiThreadEntry};
    // do something...
    legacy_api_thread.detach();
    return 0;
}

原文由 user7860670 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题