【问题标题】:is it safe to detach a thread and then let it go out of scope (and have it still running)?分离线程然后让它超出范围(并让它仍在运行)是否安全?
【发布时间】:2018-11-03 10:12:49
【问题描述】:

我有以下代码,我认为可以正常工作(请原谅愚蠢/做作的示例)。

void run_thread()
{
    std::thread t([]{
        while(true)
        {
            // keep getting chars... to stop peoples eye's hurting : )
            char c = getchar();
        }
    });

    t.detach(); // Detach thread

    // thread goes out of scope here - but is it ok because its detached??
}

int main()
{
     run_thread();    

    // Wait here forever
    while (true) {;}
}

但在重读之后,我对它产生了怀疑。线程 t 超出范围。我现在不记得在你调用 detach() 之后这样做是否安全......我认为是的,但正如我所说,我有一个挥之不去的疑问。任何人都可以确认这是好还是坏的做法?

【问题讨论】:

  • @RichardCritten 是的,我确实看到了这个事实,但它说销毁是安全的(虽然没有告诉我它仍然可以运行)。甚至分离说:Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits. After calling detach *this no longer owns any thread. 但我只是想加倍确定:)
  • 题外话,但一个字面上永远运行的线程可能会给你带来一些惊喜timsong-cpp.github.io/cppwp/n4659/…
  • @rustyx ...lol 抱歉,好吧,我会的 .. 我知道我应该做一个更好的例子:o

标签: c++ stdthread detach


【解决方案1】:

线程 t 超出范围。我现在不记得这样做是否安全 这在你调用了 detach() 之后

detach() 因为您想解除实际运行的线程与线程对象的关联。所以在} t 超出范围后,实际线程将继续运行,直到其指令完成。

如果不是detach() std::terminate 会杀死} 的线程

【讨论】:

  • 关于 std::terminate 的观点非常好。我没想到 :)
【解决方案2】:

detach 基本上释放了 std::thread 对象实例,它是实际 OS 线程的 C++“句柄”,因此以后不可能join 线程。

在大多数情况下,最好将thread 实例保留在某个全局范围内,以便您以后可以join 它,例如在退出main 之前。这样你就可以确保所有线程在主线程之前完成。

例如:

std::thread t; // can be "empty"

void run_thread()
{
    t = std::thread([]{
        while(true)
        {
            // keep getting chars...
            char c = getchar();
        }
    });

}

int main()
{
     run_thread();    

    // Wait here
    std::this_thread::sleep_for(30s);

    // Before exiting wait for the thread to finish
    if (t.joinable())
        t.join();
}

【讨论】:

  • 谢谢。我通常只使用这种方法——这就是为什么我对分离方法感到有点不舒服的原因。但我认为这个答案增加了这个问题,所以 +1 :)
【解决方案3】:

这样的用法就是分离的

【讨论】:

  • 啊唷,谢谢......这和我想的一样,但我只是想和专业人士核实一下:))
  • 仍然必须确保线程在程序(主线程)之前终止。
  • @Cheersandhth.-Alf 是的,很好,我的真实代码中正在进行一些线程同步,所以我应该没问题:)
【解决方案4】:

是的,在您的代码中是可以且安全的。但它没有任何意义。 main 函数将使用 CPU,线程函数将获得更少的 CPU 时间。您可以附加到永久线程并达到类似的行为:run_thread 永远不会退出,因此 main 永远不会退出。

void run_thread()
{
    std::thread t([]{
        while(true){/* also run forever */;}
    });

    // Wait here forever
    t.attach();
}

int main()
{
     run_thread();    
}

【讨论】:

  • 是的,对不起,这是由于我的蹩脚示例 - 我只是有示例来显示“问题”。但是您的观点已被记录:)
猜你喜欢
  • 1970-01-01
  • 2021-01-26
  • 2012-11-30
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 2014-11-06
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多