exit()和exit_group()有什么区别?

11

exit()exit_group()有什么区别?任何具有多个线程的进程都应该使用exit_group而不是exit?

回答“你为什么问这个问题”的问题 - 我们有一个大约有四十个线程的进程。当一个线程被锁定时,我们会自动退出进程,然后重新启动进程。并且我们会打印出被锁定的线程的回溯信息。我们想知道在这种情况下调用exit是否与exit_group有任何区别。

从文档中得知:此系统调用相当于exit(2),但它不仅终止调用线程,还终止调用进程的所有线程组中的所有线程 - 然而,退出进程和退出所有线程之间有什么区别。难道退出进程就等于退出所有线程吗?


1
根据文档(和使用strace实验),exit(3) 使用 exit_group - Basile Starynkevitch
C库的exit调用了exit_group系统调用。exit系统调用仅退出调用进程(在内核中,进程是一个线程)。 - Kerrek SB
2
从文档中得知:此系统调用相当于exit(2),但它不仅终止调用线程,而且会终止调用进程的线程组中的所有线程。 - Linuxios
这不是一个关于C语言的问题。exit_group() 似乎是 Linux 系统调用,在 Linux libc 实现中使用。(我检查了一个FreeBSD系统,它从来没有听说过 exit_group()。) - Arlie Stephens
1
@BasileStarynkevitch 我问这个问题是因为,当我们遇到问题时 - 我们想知道我们看到的回溯信息在所有线程上是否正确,或者它是不正确的,因为所有线程都没有正常退出而是突然终止了。 - Joe
显示剩余6条评论
1个回答

6
我知道的所有线程库(例如最近的glibcmusl-libc)都使用低级别的clone(2) 系统调用来实现它们的线程实现(有些C库甚至使用clonefork一个进程)。

clone是一个复杂的Linux系统调用。除非你是线程库实现者,否则不应该直接使用它,而只能通过库函数(例如pthread_create(3))来使用;另请参见futex(7)pthread_mutex*函数中的使用。

clone系统调用用于创建任务:线程(在多线程进程中共享地址空间)或进程。

exit_group系统调用与退出这些任务有关。

简而言之,你永远不会直接使用 exit_groupclone。这些都是由你的libc完成的。所以不要关心exit_group_Exit;你应该只使用标准库函数exit(3),它特别处理atexit(3)on_exit(3)注册的处理程序并刷新<stdio.h>缓冲区。在极少数情况下,如果你不想这样做,可以使用_exit(2)(但你可能不需要它)。
当然,如果你要从头开始重新实现自己的libc,你需要关注exit_group和clone;但否则你不需要关心它们。
如果你关心血腥的实现细节,请深入了解你的libc源代码。细节可能涉及libc版本、内核版本和编译器规范!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接