it-swarm.com.de

Was ist der Unterschied zwischen _exit () und exit () in einem herkömmlichen Linux-Fork-Exec

Ich habe versucht herauszufinden, wie der Fork-Exec-Mechanismus in Linux verwendet wird. Alles lief nach Plan, bis mich einige Webseiten verwirrten.

Es wird gesagt, dass ein untergeordneter Prozess _exit() anstelle einer einfachen exit() oder einer normalen Rückkehr von main() verwenden sollte. 

Wie ich weiß, führt die Linux-Shell jeden externen Befehl aus. Angenommen, das, was ich oben gesagt habe, ist wahr, die Schlussfolgerung ist, dass keiner dieser externen Befehle und keine andere Ausführung innerhalb der Linux-Shell normal zurückkehren kann!

Wikipedia und einige andere Webseiten behaupten, dass wir _exit() verwenden müssen, nur um zu verhindern, dass ein untergeordneter Prozess temporäre Dateien der Eltern löscht, während möglicherweise Doppelspülung der Standardpuffer auftritt. Ich verstehe zwar die erstere, aber ich habe keine Ahnung, wie eine doppelte Pufferung für ein Linux-System schädlich sein könnte.

Ich habe meinen ganzen Tag damit verbracht ... Vielen Dank für jede Klarstellung.

42
ned1986zha

Sie sollten _exit (oder sein Synonym _Exit) verwenden, um das untergeordnete Programm abzubrechen, wenn die exec fehlschlägt. In dieser Situation kann der untergeordnete Prozess die externen Daten (Dateien) des übergeordneten Prozesses stören, indem er seine atexit-Handler aufruft. seine Signalhandler aufrufen und/oder Puffer löschen.

Aus demselben Grund sollten Sie auch _exit in einem untergeordneten Prozess verwenden, der keine exec ausführt. Diese sind jedoch selten.

In allen anderen Fällen verwenden Sie einfach exit. Wie Sie sich selbst teilweise notiert haben, ist jeder - Prozess in Unix/Linux (mit Ausnahme eines, init) das Kind eines anderen Prozesses. Die Verwendung von _exit in jedem untergeordneten Prozess würde bedeuten, dass exit außerhalb von init unbrauchbar ist.

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 ...
}
40
Fred Foo

exit() leert die Puffer und führt einige andere Dinge aus, z. B. die durch atexit() registrierten Run-Funktionen. exit() ruft _end( ) auf

_exit() beendet den Prozess ohne dies zu tun. Sie rufen _exit() vom übergeordneten Prozess auf, wenn Sie beispielsweise einen Dämon erstellen.

Stellen Sie fest, dass main() eine Funktion ist? Haben Sie sich schon immer gefragt, wie es überhaupt heißt? Wenn ein Programm ausgeführt wird, stellt die von Ihnen ausgeführte Shell den ausführbaren Pfad zum 'exec'-Systemaufruf bereit, und die Steuerung wird an den Kernel übergeben, der wiederum die Startfunktion jeder ausführbaren Datei aufruft _start(), ruft Ihre main() auf, wenn main() zurückgegeben wird, dann _end(). Einige Implementierungen von C verwenden etwas andere Namen für _end() & _start(). ..

exit() und _exit() aufrufen _end()

Normalerweise - für jede main() sollte es einen & nur einen exit() Anruf geben. (oder am Ende von main() zurückkehren)

15

exit () befindet sich oben in _exit () und verwendet eine herkömmliche C-Bibliothek.

Es gibt die Unterschiede:

  1. _exit () leert den stdio-Puffer nicht, während exit () den stdio-Puffer vor dem Beenden leert.

  2. _exit () kann keinen Bereinigungsprozess durchführen, während exit () mit einer Funktion (d. h. on_exit oder at_exit) registriert werden kann, um einen Bereinigungsprozess durchzuführen, wenn vor dem Erstellen des Programms etwas ___ erforderlich ist.

exit (status) übergibt den Exit-Status einfach an _exit (status). Es wird empfohlen, bei jeder Ausführung von fork () eines von ihnen zwischen child und parent _exit () und ein anderes exit () zu verwenden.

2
Sandeep_black

Im untergeordneten Zweig einer fork() ist es normalerweise falsch, .__ zu verwenden. exit(), weil dies dazu führen kann, dass stdio-Puffer zweimal gespült werden, und temporäre Dateien werden unerwartet entfernt.

Auszug aus: http://www.unixguide.net/unix/programming/1.1.3.shtml

0
snr