使用_exit()和amp;有什么区别?在传统的Linux fork-exec中退出()?

时间:2011-03-24 17:05:47

标签: c linux return fork exit

我一直在试图弄清楚如何在Linux中使用fork-exec机制。根据计划,一切都在继续,直到一些网页开始让我迷惑。

据说,子进程应严格使用_exit()而不是简单的exit()main()的正常回报。

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

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

我花了一整天的时间...... 谢谢你的任何澄清。

4 个答案:

答案 0 :(得分:41)

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

出于同样的原因,您还应该在不执行_exit的任何子进程中使用exec,但这些很少见。

在所有其他情况下,只需使用exit即可。正如您自己部分注意到的那样, Unix / Linux中的每个进程(除了一个,init)都是另一个进程的子进程,因此在每个子进程中使用_exit意味着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 ...
}

答案 1 :(得分:16)

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

_exit()只是结束了这个过程而没有这样做。例如,在创建守护程序时,可以从父进程调用_exit()

有没有注意到main()是一个功能?有没有想过首先叫它的是什么? 当ac程序运行你运行的shell提供'exec'系统调用的可执行路径,控件被传递给内核,而内核又调用每个可执行文件_start()的启动函数,调用你的main() ,当main()返回时,则调用_end() C的某些实现对_end()&amp;的使用略有不同的名称。 _start() ...

exit()_exit()调用_end()

通常 - 对于每个main(),应该有一个&amp;只有一个exit()电话。 (或在main()

结束时返回

答案 2 :(得分:2)

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

存在差异:

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

  2. _exit()无法执行清理过程,而exit()可以注册一些函数(即on_exit或at_exit)来执行一些清理过程,如果 在存在该计划之前需要做任何事情。

  3. exit(status)只是将退出状态传递给_exit(status)。建议每当执行fork()时,其中一个在child和parent之间,一个使用_exit(),另一个使用exit()。

答案 3 :(得分:0)

  

true的子分支中,通常不正确使用   === 0,因为这可能导致stdio缓冲区被刷新两次,   和临时文件被意外删除。

摘录自:http://www.unixguide.net/unix/programming/1.1.3.shtml