GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Lernen und verwenden Sie die Systemaufrufe fork(), vfork(), wait() und exec() auf Linux-Systemen

Es hat sich herausgestellt, dass es in allen Linux/Unix-basierten Betriebssystemen gut ist, fork zu verstehen und vfork Systemaufrufe, wie sie sich verhalten, wie wir sie verwenden können und Unterschiede zwischen ihnen. Zusammen mit diesen warten und exec Systemaufrufe werden für das Spawnen von Prozessen und verschiedene andere verwandte Aufgaben verwendet.

Die meisten dieser Konzepte werden anhand von Programmierbeispielen erläutert. In diesem Artikel werde ich behandeln, was Systemaufrufe fork, vfork, exec und wait sind, ihre Unterscheidungsmerkmale und wie sie besser verwendet werden können.

fork()

fork(): Systemaufruf zum Erstellen eines untergeordneten Prozesses.

[email protected] ~}$ man fork

Dies ergibt eine Ausgabe, die erwähnt, wofür der Fork verwendet wird, die Syntax und zusammen mit allen erforderlichen Details.

Die für den Fork-Systemaufruf verwendete Syntax lautet wie folgt:

pid_t fork(void);

Der Fork-Systemaufruf erstellt einen Kindprozess, der sich von seinem Elternprozess nur in PID(Prozess-ID) unterscheidet undppid(Elternprozess-ID) . Die Ressourcenauslastung wird auf null gesetzt. Dateisperren und ausstehende Signale werden nicht vererbt. (In Linux ist „fork“ als „copy-on-write()“ implementiert “).

Hinweis:-Kopieren beim Schreiben ” -> Immer wenn ein Systemaufruf von fork() aufgerufen wird, wird eine Kopie aller Seiten (Speicher), die sich auf den übergeordneten Prozess beziehen, erstellt und vom Betriebssystem für den untergeordneten Prozess in einen separaten Speicherort geladen. Dies ist jedoch nicht in allen Fällen erforderlich und kann nur erforderlich sein, wenn ein Prozess in diesen Adressraum oder Speicherbereich schreibt, dann wird nur eine separate Kopie erstellt/bereitgestellt.

Rückgabewerte :-  PID (Prozess-ID) des untergeordneten Prozesses wird im übergeordneten Ausführungs-Thread und „Null zurückgegeben “ wird im Ausführungsthread des Kindes zurückgegeben. Es folgt das C-Programmierbeispiel, das erklärt, wie der Fork-Systemaufruf funktioniert.

[email protected] ~}$ vim 1_fork.c#include#includeInt main(void){printf("Before fork\n");fork();printf( "after fork\n");}[email protected] ~}$ [email protected] ~}$ cc 1_fork.c[email protected] ~}$ ./a.outBefore forkAfter fork[email protected] ~}$ 

Wann immer ein Systemaufruf getätigt wird, finden auf Unix/Linux-Rechnern viele Dinge hinter den Kulissen statt.

Zunächst erfolgt der Kontextwechsel vom Benutzermodus in den Kernel(system)-Modus. Dies basiert auf der Prozesspriorität und dem von uns verwendeten Unix/Linux-Betriebssystem. Im obigen C-Beispielcode verwenden wir die öffnende geschweifte Klammer „{“, die den Eintrag des Kontexts darstellt, und die schließende geschweifte Klammer „}“ dient zum Verlassen des Kontexts. Die folgende Tabelle erklärt den Kontextwechsel sehr anschaulich.

vfork()

vfork –> Kindprozess erstellen und Elternprozess blockieren.

Hinweis:- In vfork werden Signal-Handler geerbt, aber nicht geteilt.

[email protected] ~}$ man vfork

Dies ergibt eine Ausgabe, die erwähnt, wofür vfork verwendet wird, die Syntax und zusammen mit allen erforderlichen Details.

pid_t vfork(void);

vfork ist dasselbe wie fork, außer dass das Verhalten undefiniert ist, wenn der von vfork erstellte Prozess entweder andere Daten als eine Variable vom Typ pid_t modifiziert, die zum Speichern des Rückgabewerts p von vfork verwendet wird, oder eine andere Funktion zwischen dem Aufruf von _exit() oder einer der exec aufruft () Familie.

Hinweis: vfork wird manchmal als Sonderfall von Klon bezeichnet.

Es folgt das C-Programmierbeispiel für vfork(), wie es funktioniert.

[email protected] ~}$ vim 1.vfork.c#include#includeInt main(void){printf("Before fork\n");vfork(); printf("after fork\n");}[E-Mail-geschützt] ~}$ vim 1.vfork.c[E-Mail-geschützt] ~}$ cc 1.vfork.c[E-Mail-geschützt] ~}$ ./a.outBefore vforkafter vforkafter vforka.out:cxa_atexit.c:100:__new_exitfn:Behauptung `l !=NULL' fehlgeschlagen. Abgebrochen

Hinweis: – Wie bereits erläutert, ist das Verhalten des vfork-Systemaufrufs oft nicht vorhersehbar. Wie im obigen Fall hatte es zuvor einmal und danach zweimal gedruckt, aber den Aufruf mit der Funktion _exit() abgebrochen. Es ist besser, den Fork-Systemaufruf zu verwenden, sofern nicht anders, und die Verwendung von vfork so weit wie möglich zu vermeiden.

Unterschiede zwischen fork() und vfork()

Vfork() Verhalten ausführlicher im folgenden Programm erklärt.

[email protected] ~}$ cat vfork_advanced.c#include #include #include int main(){    int n =10; pid_t pid =vfork(); //Kindprozess erstellen    if (pid ==0)          //wenn es sich um einen chilenischen Prozess handelt    {        printf("Kindprozess gestartet\n"); }    else//Ausführung des übergeordneten Prozesses    {        printf("Jetzt komme ich zurück zum übergeordneten Prozess\n"); }    printf("Wert von n:%d \n",n); //Beispieldruck zur Überprüfung des "n"-Werts    return 0;}[E-Mail-geschützt] ~}$ cc vfork_advanced.c[E-Mail-geschützt] ~}$ ./a.outChild-Prozess gestartetWert von n:10Jetzt komme ich zurück zum übergeordneten Prozesswert von n:594325573a.out:cxa_atexit.c:100:__new_exitfn:Behauptung `l !=NULL' fehlgeschlagen. Abgebrochen

Hinweis: Auch wenn Sie beobachten, dass das Ergebnis von vfork nicht definiert ist. Der Wert von „n“ wurde zum ersten Mal als 10 gedruckt, was erwartet wird. Aber das nächste Mal im übergeordneten Prozess hat es irgendeinen Müllwert ausgegeben.

warten()

Der Systemaufruf wait() setzt die Ausführung des aktuellen Prozesses aus, bis ein untergeordneter Prozess beendet wurde oder bis ein Signal geliefert wurde, dessen Aktion darin besteht, den aktuellen Prozess zu beenden oder den Signal-Handler aufzurufen.

pid_t wait(int * status);

Es gibt andere Systemaufrufe im Zusammenhang mit warten wie unten,

1) waitpid() :Unterbricht die Ausführung des aktuellen Prozesses, bis ein Kind, wie durch PID-Argumente angegeben, beendet wurde oder bis ein Signal geliefert wird.

pid_t waitpid (pid_t pid, int *status, int Optionen);

2) wait3() :Unterbricht die Ausführung des aktuellen Prozesses, bis ein untergeordneter Prozess beendet wurde oder bis ein Signal geliefert wird.

pid_t wait3(int *status, int options, struct rusage *rusage);

3) wait4() :Dasselbe wie wait3(), enthält aber den pid_t-PID-Wert.

pid_t wait3(pid_t pid, int *status, int options, struct rusage *rusage);

exec()

exec() Familie von Funktionen oder Systemaufrufen ersetzt das aktuelle Prozessabbild durch ein neues Prozessabbild.

Es gibt Funktionen wie execl , execlp ,execle ,execv , execvp und execvpe werden verwendet, um eine Datei auszuführen.

Diese Funktionen sind Kombinationen von Arrays von Zeigern auf nullterminierte Zeichenfolgen, die die Argumentliste darstellen, diese wird eine Pfadvariable mit einigen Kombinationen von Umgebungsvariablen haben.

Beenden()

Diese Funktion wird für die normale Prozessbeendigung verwendet. Der Status des Prozesses wird für zukünftige Referenzzwecke erfasst. Es gibt andere ähnliche Funktionen exit(3) und _exit(). , die basierend auf dem bestehenden Prozess verwendet werden, den man verwenden oder erfassen möchte.

Schlussfolgerung:-

Die Kombinationen all dieser Systemaufrufe/Funktionen werden für die Prozesserstellung, -ausführung und -modifikation verwendet. Auch diese werden als "Shell"-Spawning-Set-of-Functions bezeichnet. Man muss diese Funktionen vorsichtig verwenden und das Ergebnis und Verhalten im Auge behalten.


Linux
  1. So verwenden Sie LVM-Snapshots zum Wiederherstellen von Linux-Systemen

  2. So installieren und verwenden Sie Git in einem Linux-System

  3. So installieren und verwenden Sie Telnet auf Linux-Systemen

  4. So verwenden Sie die Befehle strace und ltrace unter Linux

  5. So installieren und verwenden Sie Glances zur Überwachung von Linux-Systemen

So installieren und verwenden Sie Skype auf einem Linux-System. Es ist jetzt einfacher

So installieren und verwenden Sie den GCC-Compiler auf einem Linux-System

So mounten und verwenden Sie ein exFAT-Laufwerk auf einem Linux-System

So installieren und verwenden Sie Tmux (Terminal Multiplexer) im Linux-System

So installieren und verwenden Sie AsciiDoc im Linux-System

So installieren und verwenden Sie den Konsole-Terminal-Emulator im Linux-System