【问题标题】:std::thread release from inside thread functionstd::thread 从内部线程函数中释放
【发布时间】:2019-04-15 20:38:33
【问题描述】:

一个典型的工作线程是这样的:

std::thread t([](){

  ....
 });
t.join();

有没有办法从线程函数内部分离线程(因此join 应该返回)?所以线程被“分离”了,t.join()之后的代码继续运行,线程函数也继续运行。

我可以在 Windows 中使用 SetEvent 执行此操作,但我正在寻找标准解决方案。

【问题讨论】:

  • 通常的方法是直接调用t.detach() 而不是t.join()。如果你真的想要,你可以在线程中创建另一个线程并将其分离并让中间线程退出......
  • 为什么不直接调用detach 而不是join?另外,在detach 之后调用join 会抛出异常
  • 这看起来像是一个 XY 问题。通常线程不应该被分离,绝对不应该尝试从父线程中“逃脱”。
  • 作为一种解决方法,您可以从您的线程启动另一个线程并从中分离。
  • 调用t.detach()t.join() 始终应由创建线程t 的任何函数负责。

标签: c++ multithreading c++11


【解决方案1】:

如何做到这一点

线程运行的函数需要有对线程的引用。如果它有对线程的引用,那么它可以在该引用上调用detach

使用 lambda 有两种方法可以做到这一点。

通过引用捕获线程。我们可以让传递给线程的 lambda 通过引用捕获线程本身:

std::thread myThread([&]() {
    myThread.detach(); 
}); 

将线程作为输入传递给 lambda。

我们可以将引用传递给我们用来启动线程的函数,如下所示:

auto myFunc = [](std::thread& myThread) {
    myThread.detach(); 
};

// Pass a reference to yourself:
std::thread t(myFunc, std::ref(t)); 

在这里,我们将线程的引用传递给myFunc,它会在线程启动时将其分离。我们必须使用来自<utility>std::ref,因为线程会复制用于启动它们的参数除非这些参数作为reference_wrapper 传递。

detach被调用之前使用std::shared_ptr防止线程对象掉出作用域

只有在线程最终执行时myThread 仍在作用域内时,这些方法才有效。如果myThread 超出范围,这将使引用无效,并可能导致程序崩溃。

我建议使用 shared_ptr 之类的东西来解决这个问题:

auto myFunc = [](std::shared_ptr<std::thread> myThread) {
    myThread->detach(); 
};

std::shared_ptr<std::thread> t_ptr(new std::thread(myFunc, t_ptr));

【讨论】:

    猜你喜欢
    • 2018-01-02
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多