分离线程然后让它超出范围(并让它仍然运行)是否安全?

问题描述 投票:0回答:4

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

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() 之后执行此操作是否安全......我认为是的,但正如我所说,我有一个挥之不去的疑问。任何人都可以确认这是好还是坏做法?

c++ stdthread detach
4个回答
13
投票

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

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

如果不是

detach()
std::terminate
就会杀死
}

处的线程

4
投票

detach
基本上释放了
std::thread
对象实例,它是实际操作系统线程的 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
    t.join();
}

1
投票

这样的用法就是detach的


1
投票

是的,在您的代码中是可以并且安全的。但这没有任何意义。

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();    
}
© www.soinside.com 2019 - 2024. All rights reserved.