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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5422831/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:24:02  来源:igfitidea点击:

What is the difference between using _exit() & exit() in a conventional Linux fork-exec?

clinuxreturnforkexit

提问by ned1986zha

I've been trying to figure out how the fork-exec mechanism is used inside Linux. Everything was going on according to the plan until some web pages started to confuse me.

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

It is said that a child process should strictly use _exit()instead of a simple exit()or a normal return from main().

据说子进程应该严格使用_exit()而不是简单exit()或正常的 return from main()

As I know, Linux shell fork-execs every one of the external commands; assuming what I said above is true, the conclusion is that none of these external commands nor any other execution happening inside the Linux shell can do normal return!

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

Wikipedia & some other webpages claim we've got to use _exit()just to prevent a child process causing deletion of parent's temporary files while a probable double flushing of stdio buffers may happen. though I understand the former, I have no clues how a double flushing of buffers could be harmful to a Linux system.

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

I've spent my whole day on this... Thanks for any clarification.

我已经花了一整天的时间...感谢您的澄清。

采纳答案by Fred Foo

You should use _exit(or its synonym _Exit) to abort the child program when the execfails, because in this situation, the child process may interfere with the parent process' external data (files) by calling its atexithandlers, calling its signal handlers, and/or flushing buffers.

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

For the same reason, you should also use _exitin any child process that does not do an exec, but those are rare.

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

In all other cases, just use exit. As you partially noted yourself, everyprocess in Unix/Linux (except one, init) is the child of another process, so using _exitin every child process would mean that exitis useless outside of init.

在所有其他情况下,只需使用exit. 正如您部分指出的那样,Unix/Linux 中的每个进程(除了一个,init)都是另一个进程的子进程,因此_exit在每个子进程中使用将意味着exitinit.

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 ...
}

回答by Nandan Bharadwaj

exit()flushes io buffers and does some other things like run functions registered by atexit(). exit()invokes _end( )

exit()刷新 io 缓冲区并执行其他一些操作,例如运行由atexit(). exit()调用_end( )

_exit()just ends the process without doing that. You call _exit()from the parent process when creating a daemon for example.

_exit()只是结束过程而不这样做。例如,您_exit()在创建守护进程时从父进程调用。

Ever notice that main()is a function? Ever wonder what called it in the first place? When a c program runs the shell you are running in provides the executable path to 'exec' system call and the control is passed to kernel which in turn calls the startup function of every executable _start(), calls your main(), when main()returns it then calls _end()Some implementations of C use slightly different names for _end()& _start()...

有没有注意到这main()是一个函数?有没有想过最初叫它什么?当 ac 程序运行您正在运行的 shell 时,它提供了“exec”系统调用的可执行路径,并且控制权传递给内核,内核依次调用每个可执行文件的启动函数_start(),调用您的main()main()返回时调用_end()C 的一些实现使用略有不同的名称_end()& _start()...

exit()and _exit()invoke _end()

exit()_exit()调用_end()

Normally - for every main()there should be one & only one exit()call. (or return at the end of main())

通常 - 对于每一个都main()应该有一个并且只有一个exit()调用。(或在结束时返回main()

回答by Sandeep_black

exit() is on the top of _exit(), using conventional C library.

exit() 位于 _exit() 之上,使用传统的 C 库。

There are the differences:

有以下区别:

  1. _exit() won't flushes the stdio buffer while exit() flushes the stdio buffer prior to exit.

  2. _exit() can not perform clean-up process while exit() can be registered with some function ( i.e on_exit or at_exit) to perform some clean-up process if anything is required before existing the program.

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

  2. _exit() 不能执行清理过程,而 exit() 可以注册一些函数(即 on_exit 或 at_exit)来执行一些清理过程,如果在程序存在之前需要的话。

exit(status) simply passes the exit status to _exit(status). It is recommended that whenever to perform fork(), one of them between child and parent, one use _exit() and another use exit().

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

回答by snr

In the child branch of a fork(), it is normally incorrect to use exit(), because that can lead to stdio buffers being flushed twice, and temporary files being unexpectedly removed.

在 a 的子分支中fork(),使用通常是不正确的 exit(),因为这会导致 stdio 缓冲区被刷新 两次,并且临时文件被意外删除。

Excerpted from: http://www.unixguide.net/unix/programming/1.1.3.shtml

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