Fork Systemaufruf Linux

Fork System Call Linux



Der fork-Systemaufruf wird verwendet, um einen neuen Prozess zu erstellen. Der neu erstellte Prozess ist der untergeordnete Prozess. Der Prozess, der fork aufruft und einen neuen Prozess erzeugt, ist der Elternprozess. Die Kind- und Elternprozesse werden gleichzeitig ausgeführt.

Aber die Kind- und Elternprozesse befinden sich in unterschiedlichen Speicherbereichen. Diese Speicherbereiche haben denselben Inhalt, und jede Operation, die von einem Prozess ausgeführt wird, hat keinen Einfluss auf den anderen Prozess.







Wenn die untergeordneten Prozesse erstellt werden; jetzt haben beide Prozesse denselben Programmzähler (PC), sodass beide Prozesse auf denselben nächsten Befehl zeigen. Die vom übergeordneten Prozess geöffneten Dateien sind für den untergeordneten Prozess identisch.



Der untergeordnete Prozess ist genau derselbe wie sein übergeordneter Prozess, aber es gibt Unterschiede in den Prozess-IDs:



  1. Die Prozess-ID des untergeordneten Prozesses ist eine eindeutige Prozess-ID, die sich von den IDs aller anderen vorhandenen Prozesse unterscheidet.
  2. Die übergeordnete Prozess-ID ist dieselbe wie die Prozess-ID des untergeordneten Elternteils.

Eigenschaften des untergeordneten Prozesses

Im Folgenden sind einige der Eigenschaften aufgeführt, die ein untergeordneter Prozess enthält:





  1. Die CPU-Zähler und die Ressourcenauslastungen werden initialisiert, um auf Null zurückgesetzt zu werden.
  2. Wenn der Elternprozess beendet wird, empfangen die Kindprozesse kein Signal, da das PR_SET_PDEATHSIG-Attribut in prctl() zurückgesetzt wird.
  3. Der zum Aufrufen von fork() verwendete Thread erstellt den Kindprozess. Die Adresse des untergeordneten Prozesses ist also dieselbe wie die des übergeordneten Prozesses.
  4. Der Dateideskriptor des Elternprozesses wird vom Kindprozess geerbt. Zum Beispiel werden der Offset der Datei oder der Status von Flags und die E/A-Attribute von den Dateideskriptoren von Kind- und Elternprozessen geteilt. Der Dateideskriptor der Elternklasse bezieht sich also auf denselben Dateideskriptor der Kindklasse.
  5. Die Deskriptoren der offenen Nachrichtenwarteschlange des Elternprozesses werden vom Kindprozess geerbt. Wenn beispielsweise ein Dateideskriptor eine Nachricht im Elternprozess enthält, wird dieselbe Nachricht im entsprechenden Dateideskriptor des Kindprozesses vorhanden sein. Wir können also sagen, dass die Flagwerte dieser Dateideskriptoren gleich sind.
  6. In ähnlicher Weise werden offene Verzeichnisströme von den Kindprozessen geerbt.
  7. Der standardmäßige Timer-Slack-Wert der untergeordneten Klasse entspricht dem aktuellen Timer-Slack-Wert der übergeordneten Klasse.

Eigenschaften, die nicht vom Child-Prozess geerbt werden

Im Folgenden sind einige der Eigenschaften aufgeführt, die nicht von einem untergeordneten Prozess geerbt werden:

  1. Speichersperren
  2. Das anstehende Signal einer Kindklasse ist leer.
  3. Zugehörige Datensatzsperren verarbeiten (fcntl())
  4. Asynchrone E/A-Operationen und E/A-Inhalte.
  5. Benachrichtigungen zu Verzeichnisänderungen.
  6. Timer wie alarm(), setitimer() werden nicht von der untergeordneten Klasse geerbt.

Gabel() in C

Es gibt keine Argumente in fork() und der Rückgabetyp von fork() ist ganzzahlig. Sie müssen die folgenden Header-Dateien einschließen, wenn fork() verwendet wird:



#enthalten
#enthalten
#enthalten

Bei der Arbeit mit fork() kann für Typ . verwendet werden pid_t für Prozess-IDs wie pid_t ist in definiert.

In der Header-Datei ist fork() definiert, daher müssen Sie sie in Ihr Programm einbinden, um fork() verwenden zu können.

Der Rückgabetyp ist in definiert und der fork()-Aufruf ist in definiert. Daher müssen Sie beide in Ihr Programm aufnehmen, um den Systemaufruf fork() verwenden zu können.

Syntax von fork()

Die Syntax des fork()-Systemaufrufs in Linux, Ubuntu ist wie folgt:

pid_t fork(leer);

In der Syntax lautet der Rückgabetyp pid_t . Wenn der untergeordnete Prozess erfolgreich erstellt wurde, wird die PID des untergeordneten Prozesses im übergeordneten Prozess zurückgegeben und 0 wird an den untergeordneten Prozess selbst zurückgegeben.

Wenn ein Fehler auftritt, wird -1 an den übergeordneten Prozess zurückgegeben und der untergeordnete Prozess wird nicht erstellt.

No arguments are passed to fork(). 

Beispiel 1: Aufruf von fork()

Betrachten Sie das folgende Beispiel, in dem wir den Systemaufruf fork() verwendet haben, um einen neuen untergeordneten Prozess zu erstellen:

CODE:

#enthalten
#enthalten
#enthalten

inthauptsächlich()
{
Gabel();
druckenf ('Verwenden des Systemaufrufs fork() ');
Rückkehr 0;
}

AUSGANG:

Verwenden des Systemaufrufs fork()
Verwenden des Systemaufrufs fork()

In diesem Programm haben wir fork() verwendet, dies erstellt einen neuen Kindprozess. Wenn der Kindprozess erstellt wird, zeigen sowohl der Elternprozess als auch der Kindprozess auf die nächste Anweisung (derselbe Programmzähler). Auf diese Weise werden die verbleibenden Anweisungen oder C-Anweisungen so oft wie möglich ausgeführt, d. h. 2nmal, wobei n die Anzahl der fork()-Systemaufrufe ist.

Wenn der fork()-Aufruf einmal wie oben verwendet wird (21= 2) wir haben unsere Ausgabe 2 mal.

Hier, wenn der Systemaufruf fork() verwendet wird, sieht die interne Struktur wie folgt aus:

Betrachten Sie den folgenden Fall, in dem fork() viermal verwendet wird:

CODE:

#enthalten
#enthalten
#enthalten

inthauptsächlich()
{
Gabel();
Gabel();
Gabel();
Gabel();
druckenf ('Verwenden des Systemaufrufs fork()');
Rückkehr 0;
}

Ausgabe:

Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call Using fork() system call 

Jetzt ist die Gesamtzahl der erstellten Prozesse 24= 16 und wir haben unsere print-Anweisung 16 Mal ausgeführt.

Beispiel 2: Testen, ob fork() erfolgreich war

Im folgenden Beispiel haben wir das Entscheidungskonstrukt verwendet, um den von fork() zurückgegebenen Wert (int) zu testen. Und die entsprechenden Meldungen werden angezeigt:

CODE:

#enthalten
#enthalten
#enthalten

inthauptsächlich()
{
pid_t p;
P=Gabel();
wenn(P== -1)
{
druckenf ('Beim Aufrufen von fork() ist ein Fehler aufgetreten');
}
wenn(P==0)
{
druckenf („Wir befinden uns im Kinderprozess“);
}
anders
{
druckenf („Wir befinden uns im Elternprozess“);
}
Rückkehr 0;
}

AUSGANG:

Wir sind im Elternprozess
Wir sind im Kinderprozess

Im obigen Beispiel haben wir den Typ pid_t verwendet, der den Rückgabewert von fork() speichert. fork() wird online aufgerufen:

P=Gabel();

Der von fork() zurückgegebene Integer-Wert wird also in p gespeichert und dann wird p verglichen, um zu überprüfen, ob unser fork()-Aufruf erfolgreich war.

Wenn der Aufruf fork() verwendet wird und der untergeordnete Prozess erfolgreich erstellt wurde, wird die ID des untergeordneten Prozesses an den übergeordneten Prozess zurückgegeben und 0 wird an den untergeordneten Prozess zurückgegeben ID des Kindprozesses im Kindprozess selbst. Im Kindprozess ist die ID des Kindprozesses 0.

In diesem Tutorial können Sie sehen, wie Sie mit dem Fork-Systemaufruf unter Linux beginnen.