Einführung | Wenn ein Prozess endet oder mittendrin beendet wird, muss der Kernel die vom Prozess belegten Systemressourcen freigeben. Dazu gehören Dateien, die während der Ausführung des Prozesses geöffnet wurden, angeforderter Speicher usw. |
Das Beenden eines Prozesses unter Linux wird in zwei Arten unterteilt: normales Beenden und abnormales Beenden:
1.Normalerweise beenden
a. Return in der Funktion main() ausführen.
b. Rufen Sie die Funktion „exit()“ auf
c. Rufen Sie die Funktion _exit() auf2.Unnormal beenden
a. Rufen Sie wegen der Funktion an
b. Der Prozess empfängt ein Signal und das Signal bewirkt, dass das Programm beendet wird.
Unabhängig davon, welche Exit-Methode verwendet wird, führt das System letztendlich denselben Code im Kernel aus. Dieser Code wird verwendet, um den vom Prozess verwendeten offenen Dateideskriptor zu schließen und den von ihm belegten Speicher und andere Ressourcen freizugeben.
Vergleich mehrerer Exit-Methoden
1. Der Unterschied zwischen Ausstieg und Rückkehr:exit ist eine Funktion mit Parametern. Nachdem der Exit ausgeführt wurde, wird die Kontrolle an das System übergeben
return ist die Rückkehr nach Ausführung der Funktion. Nachdem renturn ausgeführt wurde, wird die Kontrolle an die aufrufende Funktion übergeben.
2. Der Unterschied zwischen Exit und Abbruch:
Exit ist die normale Beendigung des Prozesses
about ist eine abnormale Beendigung.
exit()- und _exit()-Funktionen
Die Funktionen „exit“ und „_exit“ werden beide verwendet, um den Prozess zu beenden. Wenn das Programm „exit“ oder „_exit“ ausführt, stoppt das System bedingungslos alle verbleibenden Vorgänge, löscht verschiedene Datenstrukturen und beendet die Ausführung des Prozesses.exit wird in der Header-Datei stdlib.h deklariert, während _exit() in der Header-Datei unistd.h deklariert wird. Der Parameter „exit_code“ in „exit“ ist 0, was bedeutet, dass der Prozess normal beendet wird. Wenn es sich um einen anderen Wert handelt, bedeutet dies, dass während der Programmausführung ein Fehler auftritt.
Der Unterschied zwischen exit() und _exit()
_exit() kehrt unmittelbar nach der Ausführung zum Kernel zurück, während exit() zunächst einige Bereinigungsvorgänge durchführt und dann die Kontrolle an den Kernel übergibt.Wenn die _exit-Funktion aufgerufen wird, werden alle Dateideskriptoren des Prozesses geschlossen, der Speicher bereinigt und andere Kernel-Reinigungsfunktionen ausgeführt, der Stream wird jedoch nicht aktualisiert (stdin, stdout, stderr ...). Die Exit-Funktion liegt dazwischen die _exit-Funktion Ein Wrapper für _exit, der _exit aufruft und den Stream leert, bevor er ihn aufruft.
Der größte Unterschied zwischen der Funktion „exit()“ und der Funktion „_exit()“ besteht darin, dass die Funktion „exit()“ den Öffnungsstatus der Datei prüft und den Inhalt des Dateipuffers zurück in die Datei schreibt, bevor sie das Exit-System aufruft. Da es in der Linux-Standardfunktionsbibliothek eine Operation namens „gepufferte E/A“ gibt, besteht ihr Merkmal darin, dass im Speicher für jede geöffnete Datei ein Puffer vorhanden ist. Jedes Mal, wenn eine Datei gelesen wird, werden mehrere Datensätze kontinuierlich gelesen, sodass die Datei beim nächsten Lesen direkt aus dem Speicherpuffer gelesen werden kann. Ebenso wird bei jedem Schreiben einer Datei nur in den Speicher geschrieben Wenn bestimmte Bedingungen erfüllt sind (z. B. das Erreichen einer bestimmten Anzahl oder das Vorkommen bestimmter Zeichen usw.), wird der Inhalt des Puffers sofort in die Datei geschrieben. Diese Technologie erhöht die Geschwindigkeit beim Lesen und Schreiben von Dateien erheblich, bringt aber auch ein wenig Probleme beim Programmieren mit sich. Es wird beispielsweise angenommen, dass einige Daten in die Datei geschrieben wurden. Da sie bestimmte Bedingungen nicht erfüllen, werden sie zu diesem Zeitpunkt nur im Puffer gespeichert. Verwenden Sie zum direkten Schließen die Funktion _exit() Der Prozess wird unterbrochen und die Daten im Puffer gehen verloren. Wenn Sie daher die Integrität der Daten sicherstellen möchten, müssen Sie die Funktion exit() verwenden.
Sehen wir uns den Unterschied zwischen ihnen anhand eines Funktionsbeispiels an:
Funktionsbeispiel 1: exit.c
#include #include int main() { printf("using exit----\n"); printf("This is the content in buffer\n"); exit(0); }
Das Ausführungsergebnis ist:
using exit---- This is the content in buffer
Funktionsbeispiel 2: _exit.c
#include #include int main() { printf("using _exit--\n"); printf("This is the content in buffer"); _exit(0); }
Das Ausführungsergebnis ist:
using _exit--
Die printf-Funktion verwendet gepufferte E/A. Diese Funktion liest den Datensatz automatisch aus dem Puffer, wenn sie auf das Zeilenumbruchzeichen „n“ trifft. Daher wird exit() beendet, nachdem die Daten in den Puffer geschrieben wurden, während die Funktion _exit() direkt beendet wird.
Sie können printf("Dies ist der Inhalt im Puffer"); im Funktionsbeispiel 2 auch in printf("Dies ist der Inhalt im Puffer") ändern (das heißt, am Ende von printf ein n hinzufügen, um das Ergebnis zu sehen ist. Warum passiert das?
Die unterschiedliche Reihenfolge der Beendigung der übergeordneten und untergeordneten Prozesse führt zu unterschiedlichen Ergebnissen1. Der übergeordnete Prozess endet vor dem untergeordneten Prozess: Diese Situation ist der Waisenprozess, den wir zuvor verwendet haben. Wenn der übergeordnete Prozess zuerst beendet wird, lässt das System den init-Prozess den untergeordneten Prozess übernehmen.
2. Der untergeordnete Prozess wird vor dem übergeordneten Prozess beendet und der übergeordnete Prozess ruft die Wartefunktion nicht auf
In diesem Fall wechselt der untergeordnete Prozess in einen Zombie-Zustand und bleibt dieser, bis das System neu gestartet wird. Wenn sich der untergeordnete Prozess in einem Zombie-Zustand befindet, speichert der Kernel nur einige notwendige Informationen über den Prozess, die der übergeordnete Prozess benötigt. Zu diesem Zeitpunkt belegt der untergeordnete Prozess immer Ressourcen und reduziert außerdem die maximale Anzahl von Prozessen, die das System erstellen kann.
Wie ist der Zombie-Zustand?
Ein Prozess, der beendet wurde, dessen übergeordneter Prozess sich jedoch noch nicht mit den Folgen befasst hat (Informationen über den beendeten untergeordneten Prozess erhalten und die von ihm noch belegten Ressourcen freigeben), wird als Zombie-Prozess bezeichnet.
3. Der untergeordnete Prozess wird vor dem übergeordneten Prozess beendet und der übergeordnete Prozess ruft die Wartefunktion auf
Zu diesem Zeitpunkt wartet der übergeordnete Prozess auf das Ende des untergeordneten Prozesses.Das obige ist der detaillierte Inhalt vonMethodik: Verstehen Sie die Exit-Methode des Linux-Prozesses. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!