Linux Fork-Funktion im Vergleich zu Windows CreateProcess - was wird kopiert?

8

Ich portiere Windows-Anwendung auf Linux. Ich verwende CreateProcess unter Windows, um untergeordnete Prozesse auszuführen und alle Standard-Streams umzuleiten (ein, aus, Fehler). Die Umleitung von Streams ist kritisch. Der Hauptprozess sendet Daten an untergeordnete Elemente und empfängt deren Ausgaben und Fehlermeldungen. Hauptprozess ist sehr groß mit viel Speicher und Threads, und untergeordnete Prozesse sind klein. Unter Linux sehe ich, dass fork -Funktion ähnliche Funktionalität wie CreateProcess unter Windows hat. Das Handbuch sagt jedoch, dass fork "Elternprozesskopie" erstellt, einschließlich Code, Daten und Stapel. Bedeutet es, dass ich, wenn ich eine Kopie eines riesigen Prozesses anlege, der 1 GB Speicher verbraucht, nur um ein sehr einfaches Kommandozeilen-Tool auszuführen, das 1 MB Speicher selbst verwendet, muss ich zuerst 1 GB Speicher mit fork duplizieren, und dann diese 1 GB durch 1 MB Prozess ersetzen? Also, wenn ich 100 Threads habe, wird es erforderlich sein, 100 GB Speicher zu haben, um 100 Prozesse auszuführen, die nur 100 MB Speicher benötigen, um zu laufen? Was ist mit anderen Threads im Parent-Prozess, die über fork execution nicht wissen, was werden sie tun? Was fork Funktion tut "unter der Haube" und ist es wirklich effektive Möglichkeit, eine Menge von kleinen Kind-Prozesse von riesigen Eltern zu erstellen?

    
Vitaliy 12.02.2014, 15:42
quelle

5 Antworten

7

Wenn Sie fork() aufrufen, wird zunächst nur Ihre virtuelle Maschine kopiert, und alle Seiten werden als schreibgeschützt markiert. Ihr neuer untergeordneter Prozess verfügt über eine logische Kopie der VM Ihrer übergeordneten Prozesse, benötigt jedoch kein zusätzliches RAM, bis Sie tatsächlich mit dem Schreiben beginnen.

Wie bei Threads erstellt fork nur einen neuen Thread im untergeordneten Prozess, der einer Kopie des aufrufenden Threads ähnelt.

Sobald Sie eine der exec -Familien aufrufen (was ich annehmen möchte), wird Ihr gesamtes Prozessabbild durch ein neues ersetzt und nur Dateideskriptoren werden beibehalten.

Wenn Ihr Parent-Prozess viele offene Dateideskriptoren enthält, sollten Sie /proc/self/fd durchgehen und alle Dateideskriptoren in dem Kind, das Sie nicht benötigen, schließen.

    
Sergey L. 12.02.2014, 15:48
quelle
2

Die Kopien sind "copy-on-write". Wenn also Ihr untergeordneter Prozess die Daten nicht ändert, wird kein Speicher neben dem Vaterprozess verwendet. Nach einem fork() erstellt der untergeordnete Prozess normalerweise exec() , um das Programm dieses Prozesses durch einen anderen zu ersetzen, und dann wird der gesamte Speicher trotzdem gelöscht.

    
Alfe 12.02.2014 15:47
quelle
2

fork teilt Ihren Prozess im Wesentlichen in zwei Teile auf, wobei sowohl der Eltern- als auch der Kindprozess nach dem Funktionsaufruf fork an der Anweisung fortgesetzt werden. Der Rückgabewert im untergeordneten Prozess ist jedoch 0, während es im übergeordneten Prozess die Prozess-ID des untergeordneten Prozesses ist.

Die Erstellung des Child-Prozesses ist extrem schnell, da es die gleichen Seiten wie die Eltern verwendet. Die Seiten sind als Copy-on-Write (COW) markiert, so dass, wenn einer der Prozesse die Seite ändert, der andere nicht davon betroffen ist. Sobald der Kindprozess existiert, ruft er normalerweise eine der exec -Funktionen auf, um sich durch ein Bild zu ersetzen. Windows hat keine Entsprechung zu fork , stattdessen können Sie mit dem Aufruf CreateProcess nur einen neuen Prozess starten.

Es gibt eine Alternative zu fork namens klon , die Ihnen viel mehr Kontrolle darüber gibt, was passiert, wenn die neuer Prozess wird gestartet. Zum Beispiel können Sie eine Funktion angeben, um den neuen Prozess aufzurufen.

    
Sean 12.02.2014 16:00
quelle
1

Ich habe CreateProcess nicht verwendet, aber fork() ist keine exakte Kopie des Prozesses. Es erstellt einen untergeordneten Prozess, aber das Kind beginnt seine Ausführung mit der Anweisung selbe , in der das übergeordnete Element fork aufgerufen hat, und wird von dort fortgesetzt.

Ich empfehle, Kapitel 5 von Drei einfache Stücke OS-Buch. Dies könnte Ihnen den Einstieg erleichtern und Sie könnten den von Ihnen gesuchten Kind-Launch-Anruf finden.

    
ArthurChamz 12.02.2014 15:51
quelle
1

Der gegabelte untergeordnete Prozess hat fast alle übergeordneten Funktionen kopiert: Speicher, Deskriptoren, Text usw. Die einzige Ausnahme sind die Threads der Eltern, sie werden nicht kopiert.

    
MichaelGoren 12.02.2014 15:59
quelle

Tags und Links