我有一个关于主线程和同一进程中其他线程的问题。当主函数返回时,其他线程也退出吗?我对此感到困惑。
考虑以下测试代码:
void* test1(void *arg)
{
unsigned int i = 0;
while (1){
i+=1;
}
return NULL;
}
void* test2(void *arg)
{
long double i = 1.0;
while (1){
i *= 1.1;
}
return NULL;
}
void startThread ( void * (*run)(void*), void *arg) {
pthread_t t;
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0
|| pthread_create(&t, &attr, run, arg) != 0
|| pthread_attr_destroy(&attr) != 0
|| pthread_detach(t) != 0) {
printf("Unable to launch a thread\n");
exit(1);
}
}
int main()
{
startThread(test1, NULL);
startThread(test2, NULL);
sleep(4);
printf("main thread return.\n");
return 0;
}
字符串
当“main thread return.”打印出来时,线程test1和test2也退出了,谁能告诉我为什么?
4条答案
按热度按时间bfnvny8b1#
当主线程返回时(即,您从
main
函数返回),它会终止整个进程。这包括所有其他线程。当您调用exit
时也会发生同样的事情。您可以通过调用pthread_exit
来避免这种情况。pthread_detach
的目的是让你不需要加入其他线程来释放它们的资源。分离一个线程并不能使它在进程终止后仍然存在,它仍然会和其他线程一起被销毁沿着。m2xkgtsf2#
您应该在每个新线程上使用
pthread_join()
,通知调用线程等待子线程,挂起执行-并退出进程-直到这些线程终止。在创建的线程上调用
pthread_detach
不会在进程退出后保留它们。在Linux man page中:detached属性仅仅决定线程终止时系统的行为;如果进程使用exit(3)终止(或者等价地,如果主线程返回),它不会阻止线程终止。
你有时会看到
main
中使用pthread_exit
而不是显式的pthread_join
调用,其意图是以这种方式退出main
将允许其他线程继续运行。实际上,linux man page明确声明:为了允许其他线程继续执行,主线程应该通过调用pthread_exit()而不是exit(3)来终止。
但我不知道这是否是所有平台上的预期行为,我一直坚持使用
pthread_join
。pthread_join
需要pthread_t
作为目标线程,所以你的代码需要做一些修改,因为你需要在调用pthread_join
之前创建两个线程来等待它们。所以你不能在startThread
中调用它。你需要返回一个pthread_t
,或者将一个指向pthread_t
的指针传递给你的startThread
函数。w6lpcovy3#
从
main()
返回时,进程中的所有线程都将终止。libc
库负责在main()
函数返回时调用exit()
来实现此行为。反过来,exit()
函数将最终调用名为_exit()
的精简 Package 器函数,(从libc
v2.3开始)将最终调用exit_group系统调用并结束您的进程,同时终止其所有线程。这最后一个系统调用是您注意到的行为的原因。
我们可以在
_exit()
手册here中看到这个微妙的注解:字符串
如果你的目的是避免这种行为,唯一的选择是调用
pthread_exit
,这将结束你的主线程,并防止你返回到libc
的__libc_start_main()
函数。chhkpiq44#
作为对同一主题的旁白,我想指出在我看来APUE第三版中的不准确之处在7.3节中,它说“正常终止有五种方式”,其中包括“调用pthread_exit(第11.5节)从最后一个线程”。在我看来,这是不正确的,因为main仍然在运行(并且pthread_exit不会终止程序,因为main会这样做)或者main已经返回,所以终止程序,正如本文正确指出的那样。