传统Linux fork-exec中使用_exit()和exit()之间有什么区别?

我一直在试图弄清楚在Linux内部如何使用fork-exec机制。 一切都按照计划进行,直到一些网页开始混淆我。

据说一个subprocess应该严格使用_exit()而不是简单的exit()或者main()的正常返回。

据我所知,Linuxshellfork-execs每一个外部命令; 假设我上面说的是真的,结论是这些外部命令和Linux shell内部发生的任何其他执行都不能正常返回!

维基百科和其他一些网页声称,我们必须使用_exit()只是为了防止subprocess删除父的临时文件,而可能的双重刷新stdio缓冲区可能会发生。 虽然我理解前者,但是我没有线索,双缓冲区的刷新对Linux系统是有害的。

我花了整整一天的时间…感谢您的任何澄清。

exec失败时,应该使用_exit (或其同义词_Exit )来中止exec ,因为在这种情况下,subprocess可能通过调用它的atexit处理程序来干扰父进程的外部数据(文件),调用其信号处理程序,和/或冲洗缓冲区。

出于同样的原因,你也应该在任何不执行execsubprocess中使用_exit ,但是这很less见。

在其他所有情况下,只需使用exit 。 正如你自己部分注意到的那样,Unix / Linux中的每个进程(除了init )都是另一个进程的subprocess,所以在每个subprocess中使用_exit意味着init之外的进程是无用的。

 switch (fork()) { case 0: // we're the child execlp("some", "program", NULL); _exit(1); // <-- HERE case -1: // error, no fork done ... default: // we're the parent ... } 

exit()刷新io缓冲区,并执行一些其他的事情,如由atexit()注册的运行函数。 exit()调用_end( )

_exit()仅仅是结束了这个过程。 例如,在创build守护进程时,可以从父进程调用_exit()

有没有注意到main()是一个函数? 有没有想过是什么叫它呢? 当ac程序运行你正在运行的shell时,提供了'exec'系统调用的可执行path,控制权被传递给内核,内核依次调用每个可执行文件_start()的启动函数,调用main() main()返回它然后调用_end() C的一些实现使用_end() &_ _start()稍微不同的名称…

exit()_exit()调用_end()

通常 – 对于每个main()应该只有一个exit()调用。 (或者在main()的末尾返回)

exit()位于_exit()的顶部,使用传统的C库。

有差异:

  1. 当exit()在退出之前刷新stdio缓冲区时,_exit()不会刷新stdio缓冲区。

  2. _exit()不能执行清理过程,而exit()可以用某个函数(例如,on_exit或at_exit)注册,如果在程序存在之前需要任何东西,就执行一些清理过程。

退出(状态)只是将退出状态传递给_exit(状态)。 build议每当执行fork(),其中一个父子之间,一个使用_exit()和另一个使用exit()。