在下面的列表中,我希望当我在创建线程的行之后调用t.detach()
时,线程t
将在后台运行,而printf("quit the main function now \n")
将被调用然后main
将退出。
#include <thread>
#include <iostream>
void hello3(int* i)
{
for (int j = 0; j < 100; j++)
{
*i = *i + 1;
printf("From new thread %d \n", *i);
fflush(stdout);
}
char c = getchar();
}
int main()
{
int i;
i = 0;
std::thread t(hello3, &i);
t.detach();
printf("quit the main function now \n");
fflush(stdout);
return 0;
}
然而,从它在屏幕上打印的内容来看并非如此。它打印
From new thread 1
From new thread 2
....
From new thread 99
quit the main function now.
看起来main
函数在执行命令printf("quit the main function now \n");
之前等待线程完成并退出。
你能解释一下它为什么吗?我在这里缺少什么?
答案 0 :(得分:4)
问题是你的线程太快了。
在主要有机会继续之前,它能够打印所有100个字符串。
尝试让线程变慢,你会在线程之前看到主printf
。
答案 1 :(得分:3)
根据您的操作系统调度,它会发生。此外,线程的速度也会影响输出。如果您停止线程(例如,将100更改为500),您将首先看到该消息。
我刚刚执行了代码并且现在退出了主要功能。&#34;消息首先出现 ,如下所示:
quit the main function now
From new thread 1
From new thread 2
From new thread 3
From new thread 4
...
你对detach
:
从调用线程中分离由对象表示的线程,允许它们彼此独立地执行。
但这并不能保证消息&#34;现在退出主要功能&#34;将首先出现,尽管很可能。
答案 2 :(得分:1)
看起来main函数在执行命令printf之前等待线程完成(“现在退出main函数\ n”);并退出。
这是因为当您创建一个线程时,它会被调度执行,但跨线程的事件顺序不再是顺序的,有序的或确定的。在程序的某些运行中,hello3
的输出将在quit the main function now
之前发生,在某些运行中它将在之后打印,并且在某些运行中,输出将是交错的。这是一种未定义的行为,通常称为“竞争条件”。在大多数(但不是全部)情况下,hello3
的输出打印最后,因为在设置线程时会有一些开销(因操作系统和处理器而异),所以需要几微秒正确构建线程并准备执行需要花费很长时间才能使printf
函数中的main
语句在线程准备好运行之前已经有时间执行并flush
。
如果你想要明确证明事情是同时运行的,你应该在quit语句之前在主线程中添加更多的工作,这样在线程准备开始执行之前主函数就不可能完成。
答案 3 :(得分:0)
您的代码存在两个主要问题:
一旦 main 函数退出,您就会有未定义的行为,因为分离线程引用的变量 i 不再存在。
一旦 main 函数返回后整个过程结束,分离的线程也会死亡。