使用_exit()&;之间有什么区别;在传统的Linux fork exec中使用exit()?
我一直在试图弄清楚fork-exec机制在Linux中是如何使用的。一切都按照计划进行,直到一些网页开始让我困惑 据说子进程应该严格使用使用_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
\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的努力->答案在那里->