Linux / Perl - Was passiert, wenn ein Prozess gespalten wird?

2132
somebody

Ich habe über Fork gelesen und was ich verstehe, der Prozess wird geklont, aber welcher Prozess? Das Skript selbst oder der Prozess, mit dem das Skript gestartet wurde?

Zum Beispiel:

Ich führe rTorrent auf meinem Rechner aus und wenn ein Torrent abgeschlossen ist, habe ich ein Skript dagegen ausgeführt. Dieses Skript ruft Daten aus dem Web ab, sodass der Vorgang einige Sekunden dauert. Während dieser Zeit ist mein Rtorrent-Prozess eingefroren. Also habe ich die Skriptgabel mit folgendem gemacht

my $pid = fork(); if ($pid) == 0) { blah blah blah; exit 0; } 

Wenn ich dieses Skript über die CLI ausführe, wird es innerhalb einer Sekunde in die Shell zurückgegeben, während es im Hintergrund läuft, genau wie ich es mir vorgestellt hatte. Wenn ich es jedoch von rTorrent aus laufe, scheint es noch langsamer als zuvor zu sein. Was wurde genau gegabelt? Hat sich der rtorrent-Prozess selbst geklont, und mein Skript ist darin ausgeführt worden, oder hat sich mein Skript selbst geklont? Ich hoffe das macht Sinn.

5
Sie sind wahrscheinlich besser auf Stackoverflow zu fragen. Unfundednut vor 14 Jahren 0
rTorrent verfügt möglicherweise über Setup-Pipes für den Standardwert des Kindes. In diesem Fall müssen Sie sie möglicherweise schließen (oder schließen und die Ausgabedeskriptoren in eine Protokolldatei aufnehmen, wenn dies wichtig ist), bevor rTorrent fortgesetzt wird. Chris Johnsen vor 14 Jahren 1

1 Antwort auf die Frage

3
Greg Bacon

Aus der erweiterten Programmierung in der UNIX-Umgebung von W. Richard Stevens (S. 188):

8.3 forkFunktion

Der einzige Weg, ein neuer Prozess durch die Unix - Kernel erstellt wird, ist, wenn ein bestehender Prozess die Anruf forkFunktion. (Dies gilt nicht für die speziellen Prozesse, die wir im vorherigen Abschnitt erwähnt haben - Swapper init, und pagedaemon. Diese Prozesse werden vom Kernel als Teil des Bootstrappings speziell erstellt.)

#include <sys/types.h> #include <unistd.h>  pid_t fork(void); /* Returns: 0 in child, process ID of child in parent, -1 on error */ 

Der neu erstellte Prozess forkwird als untergeordneter Prozess bezeichnet . Die Funktion wird einmal aufgerufen, kehrt jedoch zweimal zurück. Der einzige Unterschied bei den Rückgaben ist, dass der Rückgabewert im untergeordneten Element 0 ist, während der Rückgabewert im übergeordneten Element die Prozess-ID des neuen untergeordneten Elements ist. Der Grund, warum die untergeordnete Prozess-ID an das übergeordnete Element zurückgegeben wird, liegt darin, dass ein Prozess über mehrere untergeordnete Elemente verfügen kann. Daher gibt es keine Funktion, die es einem Prozess ermöglicht, die Prozess-IDs seiner untergeordneten Elemente abzurufen. Der Grund für die forkRückgabe von 0 an das untergeordnete Element liegt darin, dass ein Prozess nur ein einziges übergeordnetes Element haben kann, sodass das untergeordnete Element immer aufrufen kanngetppid, um die Prozess-ID des übergeordneten Elements abzurufen. (Die Prozess-ID 0 wird vom Swapper immer verwendet. Daher kann 0 nicht die Prozess-ID eines untergeordneten Elements sein.)

Sowohl das untergeordnete als auch das übergeordnete Element führen die Ausführung mit der Anweisung aus, die auf den Aufruf von folgt fork. Das Kind ist eine Kopie des Elternteils. Das untergeordnete Element erhält beispielsweise eine Kopie des Datenbereichs, des Heap-Speichers und des Stapels des übergeordneten Elements. Beachten Sie, dass dies eine Kopie für das untergeordnete Element ist - das übergeordnete und untergeordnete Element teilen sich diese Speicherbereiche nicht. In den meisten Fällen teilen Eltern und Kinder das Textsegment (Abschnitt 7.6), wenn es schreibgeschützt ist.

Unter Linux forkruft der Perl- Operator das System auf forkund kehrt undefbei einem Fehler zurück, statt -1.

Stevens gibt Listen (S. 192) der vererbten Eigenschaften und Unterschiede zwischen den Elternprozessen und ihren verzweigten Kindern an:

Neben offenen Dateien gibt es zahlreiche andere Eigenschaften des übergeordneten Elements, die vom untergeordneten Element geerbt werden:

  • echte Benutzer-ID, echte Gruppen-ID, effektive Benutzer-ID, effektive Gruppen-ID
  • ergänzende Gruppen-IDs
  • Prozessgruppen-ID
  • Session-ID
  • Bedienterminal
  • Set-Benutzer-ID-Flag und Set-Gruppen-ID-Flag
  • aktuelles Arbeitsverzeichnis
  • Wurzelverzeichnis
  • Erstellungsmaske für den Dateimodus
  • Signalmaske und Dispositionen
  • das close-on-exec-Flag für alle geöffneten Dateideskriptoren
  • Umgebung
  • angehängte gemeinsam genutzte Speichersegmente
  • Ressourcengrenzen

Die Unterschiede zwischen Eltern und Kind sind

  • der Rückgabewert von fork
  • Die Prozess-IDs sind unterschiedlich
  • Die beiden Prozesse haben unterschiedliche übergeordnete Prozess-IDs - die übergeordnete Prozess-ID des untergeordneten Elements ist das übergeordnete Element. Die übergeordnete Prozess-ID des übergeordneten Elements ändert sich nicht
  • das Kind Werte für tms_utime, tms_stime, tms_cutime, undtms_ustime auf 0 gesetzt
  • Dateisperren, die vom übergeordneten Element festgelegt werden, werden nicht vom untergeordneten Element geerbt
  • ausstehende Alarme werden für das Kind gelöscht
  • Der Satz anstehender Signale für das untergeordnete Element wird auf den leeren Satz gesetzt