使用_exit()&;之间有什么区别;在传统的Linux fork exec中使用exit()?

使用_exit()&;之间有什么区别;在传统的Linux fork exec中使用exit()?,c,linux,return,fork,exit,C,Linux,Return,Fork,Exit,我一直在试图弄清楚fork-exec机制在Linux中是如何使用的。一切都按照计划进行,直到一些网页开始让我困惑 据说子进程应该严格使用\u exit(),而不是简单的exit()或从main()正常返回 据我所知,Linux shell fork执行每一个外部命令;假设我上面所说的是真的,那么结论是这些外部命令或Linux shell中发生的任何其他执行都不能正常返回 Wikipedia&其他一些网页声称,我们必须使用\u exit(),以防止子进程删除父进程的临时文件,同时可能发生stdio

我一直在试图弄清楚fork-exec机制在Linux中是如何使用的。一切都按照计划进行,直到一些网页开始让我困惑

据说子进程应该严格使用
\u exit()
,而不是简单的
exit()
或从
main()正常返回

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

Wikipedia&其他一些网页声称,我们必须使用
\u exit()
,以防止子进程删除父进程的临时文件,同时可能发生stdio缓冲区的双重刷新。虽然我理解前者,但我不知道缓冲区的双重刷新如何对Linux系统有害

我一整天都在这上面。。。 感谢您的澄清。

当执行失败时,您应该使用(或其同义词
\u Exit
)中止子程序,因为在这种情况下,子进程可能会通过调用其
atexit
处理程序、调用其信号处理程序来干扰父进程的外部数据(文件),和/或冲洗缓冲器

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

在所有其他情况下,只需使用
exit
。正如您部分提到的,Unix/Linux中的每个进程(除了一个,
init
)都是另一个进程的子进程,因此在每个子进程中使用
\u 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 ...
}
开关(fork()){
案例0:
//我们是孩子
execlp(“某些”、“程序”,NULL);
_exit(1);//
exit()
刷新io缓冲区,并执行一些其他操作,如运行由
atexit()注册的函数
exit()
调用
\u end()

\u exit()
只是结束进程而不执行此操作。例如,在创建守护进程时,可以从父进程调用
\u exit()

有没有注意到
main()
是一个函数?有没有想过最初是什么调用它的? 当一个c程序运行您正在运行的shell时,它提供了“exec”系统调用的可执行路径,控制权被传递给内核,内核依次调用每个可执行的启动函数
\u start()
,调用您的
main()
,当
main()
返回它时,则调用
\u end()
C的一些实现对
\u end()
\u start()
使用稍微不同的名称

exit()
\u exit()
调用
\u end()

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

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

它们之间有区别:

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

  • _exit()无法执行清理过程,而exit()可以注册到某个函数(即在_exit或在_exit)中,以便在以下情况下执行某些清理过程: 在程序存在之前,需要做任何事情

  • exit(status)只是将退出状态传递给_exit(status)。建议无论何时执行fork(),其中一个在子级和父级之间,一个使用_exit(),另一个使用exit()

    fork()
    的子分支中,使用
    exit()
    ,因为这会导致stdio缓冲区被刷新两次, 以及意外删除的临时文件


    摘录自:

    非常感谢。我现在感觉好多了;虽然两次刷新缓冲区仍然有问题,但对我来说没有任何意义。@ned1986zha:在
    fork()的时候
    ,stdio缓冲区中可能有数据。如果父级和子级都刷新这些缓冲区,则该数据将在输出中出现两次。如果
    exec()
    成功,因为在这种情况下,新执行的进程从新的stdio缓冲区开始。@ned1986zha:是的,
    stdio
    缓冲区是一个C库机制。可能也有操作系统提供的缓冲区,但这并不重要,因为
    fork()
    不会复制它。@Bin:正如上面的注释所说,
    \u exit()
    确保不会刷新C库级(userspace stdio)缓冲区-因为这些缓冲区被
    fork()复制(因为它们是userspace,内核不知道)。任何内核级缓冲区都会被刷新,但这没关系,因为
    fork()不会复制内核级缓冲区
    @Bin:当进程被内核终止时,文件描述符会关闭,但stdio缓冲区不会被刷新-因为内核对这些缓冲区一无所知,它们完全是用户空间C库的产物。重复的。同样相关的:不好,作为一个盗贼是不好的。尊重别人的隐私s的努力->答案在那里->