Multiprocessing Fork () vs Spawn ()

Sep 28 2020

Ich habe die Beschreibung der beiden aus dem Python-Dokument gelesen :

laichen

Der übergeordnete Prozess startet einen neuen Python-Interpreter-Prozess. Der untergeordnete Prozess erbt nur die Ressourcen, die zum Ausführen der Methode run () der Prozessobjekte erforderlich sind. Insbesondere werden unnötige Dateideskriptoren und Handles aus dem übergeordneten Prozess nicht vererbt. Das Starten eines Prozesses mit dieser Methode ist im Vergleich zur Verwendung von Fork oder Forkserver ziemlich langsam. [Verfügbar unter Unix und Windows. Die Standardeinstellung unter Windows und MacOS.]

Gabel

Der übergeordnete Prozess verwendet os.fork (), um den Python-Interpreter zu teilen. Der untergeordnete Prozess ist zu Beginn praktisch identisch mit dem übergeordneten Prozess. Alle Ressourcen des übergeordneten Elements werden vom untergeordneten Prozess geerbt. Beachten Sie, dass das sichere Verzweigen eines Multithread-Prozesses problematisch ist. [Nur unter Unix verfügbar. Die Standardeinstellung unter Unix.]

Und meine Frage ist:

  1. Ist es so, dass die Gabel viel schneller ist, weil sie nicht versucht zu identifizieren, welche Ressourcen kopiert werden sollen?
  2. Ist es so, dass Fork, da es alles dupliziert, im Vergleich zu spawn () viel mehr Ressourcen "verschwenden" würde?

Antworten

3 Darkonaut Sep 28 2020 at 12:25
  1. Ist es so, dass die Gabel viel schneller ist, weil sie nicht versucht zu identifizieren, welche Ressourcen kopiert werden sollen?

Ja, es geht viel schneller. Der Kernel kann den gesamten Prozess klonen und kopiert nur geänderte Speicherseiten als Ganzes . Es ist nicht erforderlich, Ressourcen an einen neuen Prozess weiterzuleiten und den Interpreter von Grund auf neu zu starten.

  1. Ist es so, dass Fork, da es alles dupliziert, im Vergleich zu spawn () viel mehr Ressourcen "verschwenden" würde?

Fork auf modernen Kerneln "kopiert nur beim Schreiben" und betrifft nur Speicherseiten, die sich tatsächlich ändern. Die Einschränkung ist, dass "Schreiben" bereits das bloße Iterieren über ein Objekt in CPython umfasst. Dies liegt daran, dass der Referenzzähler für das Objekt erhöht wird.

Wenn Sie lange laufende Prozesse mit vielen kleinen Objekten verwenden, kann dies bedeuten, dass Sie mehr Speicher verschwenden als mit Spawn. Anekdotisch erinnere ich mich an Facebook, das behauptete, die Speichernutzung durch den Wechsel von "Fork" zu "Spawn" für ihre Python-Prozesse erheblich reduziert zu haben.