wie man einen untergeordneten Prozess beendet – _exit() vs. exit
Lesezeit: 3 Minuten
Hilfsmethode
Betrachten Sie dieses Code-Snippet:
pid_t cpid = fork();
if (cpid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0) { // in child
execvp(argv[1], argv + 1);
perror("execvp");
_exit(EXIT_FAILURE);
}
// in parent
Wie soll ich den untergeordneten Prozess beenden, wenn execvp zurückkehrt? Soll ich exit() oder _exit() verwenden?
Codierer mit variabler Länge
Solltest du unbedingt nutzen _Exit(). exit() ruft die Funktionen auf, die Sie mit hinzugefügt haben atexit() und löscht Dateien, die mit erstellt wurden tmpfile(). Da der übergeordnete Prozess wirklich derjenige ist, der diese Dinge erledigen möchte, wenn er existiert, sollten Sie anrufen _Exit()die nichts davon tut.
Notiz _Exit() mit einem großen E. _exit(2) ist wahrscheinlich nicht das, was Sie direkt anrufen möchten. exit(3) und _Exit(3) wird dies für Sie anrufen. Wenn Sie nicht haben _Exit(3)dann ja, _exit() ist das, was du wolltest.
+1 Sie möchten, dass der fehlgeschlagene untergeordnete Prozess leise beendet wird, als wäre er nie erstellt worden.
– John Kugelmann
24. Februar 2010 um 21:49 Uhr
Nun, da der alte C-Standard es dem Linker ermöglichte, die Groß-/Kleinschreibung aufzulösen, kann _Exit() keine Standardbibliotheksfunktion sein, da dies mit dem älteren _exit() in Konflikt geraten würde. Es tut uns leid.
– Josua
24. Februar 2010 um 21:50 Uhr
Andererseits. _Exit(3) ist eine Standard-C-Bibliothek (ISO C99). _exit(2) ist ein POSIX.1-Systemaufruf und kein C-Standard.
– Codierer mit variabler Länge
25. Februar 2010 um 1:06 Uhr
Ob offene Ressourcen wie Dateien nach dem Aufruf geschlossen werden _Exit ist die Implementierung definiert. Sie möchten dieses Verhalten wahrscheinlich nicht (in Bezug auf nicht geleerte Streams). Alle Manpages, die ich gesehen habe, sagen das _exit löscht keine Streams, daher ist es sicherer, wenn eine Datei nicht geleerten Inhalt hat, wenn ein Forking stattfindet. Die Tatsache, dass _exit ist nicht Standard C ist ein strittiger Punkt, wie fork ist auch Unix-spezifisch. Der C-Normenausschuss kann besondere Gründe haben, ihn einzuführen _Exitaber es gibt keinen Grund für Unix-Programmierer, sich zu ändern _exit zu _Exit überhaupt. @VariableLengthCoder
– Yongwei Wu
13. Dezember 2017 um 4:39 Uhr
Das Kind von fork() sollte immer _exit() aufrufen.
Der Aufruf von exit() ist stattdessen eine gute Möglichkeit, um zu bewirken, dass ausstehende stdio-Puffer zweimal geleert werden.
exec gibt nur einen Fehler zurück, in dem Sie _exit aufrufen.
– Josua
14. Februar 2014 um 4:01 Uhr
Nikolaus Guillaume
execvp beendet das Kind, wenn es erfolgreich ist, sodass Sie es nicht beenden müssen.
Bei execve Fehler verwende ich einfach exit(EXIT_FAILURE); im Kind.
Es sieht also so aus, als wäre es besser zu verwenden _exit() in einem Fork-Kind, besonders wenn Sie in C++ sind: p Danke für Ihre Frage, ich habe etwas gelernt: D
Es kommt auf das gewünschte Verhalten an: man -s 3 exit und man _exit für weitere Details zu Ihrem System. Im Allgemeinen glaube ich, dass _exit keine Funktionen ausführt, die bei atexit() registriert sind, während exit dies tut (diese Funktionen rufen besser nicht exit auf – sonst erhalten Sie eine Rekursion).
Im Allgemeinen würde ich exit gegenüber _exit bevorzugen, außer in Funktionen, die mit atexit registriert sind, in denen ich bei Bedarf _exit aufrufen würde.
ImanKh
exit() ist eine ANSI-C-Funktion und daher betriebssystemunabhängig. Es schließt alle ANSI-C-Standardfunktionen. _exit() wird von angerufen exit() um betriebssystemabhängige Funktionalitäten zu schließen, weil exit() hat keine Ahnung davon. (exit ist betriebssystemunabhängig)