Python Multiprocessing Dokumentation Beispiel

8

Ich versuche Python Multiprocessing zu lernen.

Ссылка aus dem Beispiel "Um die einzelnen beteiligten Prozess-IDs anzuzeigen, hier ein erweitertes Beispiel : "

%Vor%

Was genau betrachte ich? Ich sehe, dass def f (name): wird nach der Info ('Hauptleitung') ist beendet, aber dieser synchrone Anruf wäre sowieso Standard. Ich sehe, dass die gleiche Prozessinformation ("Hauptlinie") die Eltern-PID von def f (Name) ist: aber nicht sicher, was "Multiprocessing" darüber ist.

Auch mit join () "Blockiere den aufrufenden Thread, bis der Prozess, dessen Join () -Methode aufgerufen wird, endet". Ich weiß nicht, was der aufrufende Thread sein würde. In diesem Beispiel würde was beitreten () blockiert werden?

    
dman 11.08.2013, 05:15
quelle

1 Antwort

25

Wie multiprocessing funktioniert, auf den Punkt gebracht:

  • Process() spawns ( fork oder ähnlich auf Unix-ähnlichen Systemen) eine Kopie des ursprünglichen Programms (unter Windows, dem ein reales fork fehlt, ist dies schwierig und erfordert die besondere Sorgfalt, die in der Moduldokumentation vermerkt ist) / li>
  • Die Kopie kommuniziert mit dem Original, um herauszufinden, dass (a) es eine Kopie ist und (b) es ausgehen und die Funktion target= aufrufen sollte (siehe unten).
  • Zu diesem Zeitpunkt sind das Original und die Kopie jetzt unterschiedlich und unabhängig und können gleichzeitig ausgeführt werden.

Da es sich um unabhängige Prozesse handelt, haben sie jetzt unabhängige Global Interpreter Locks (in CPython), so dass beide bis zu 100% einer CPU in einer Multi-CPU-Box verwenden können, solange sie nicht für andere niedrigere CPUs kämpfen. Level (OS) Ressourcen. Das ist der "Multiprocessing" -Teil.

Natürlich müssen Sie irgendwann Daten zwischen diesen vermeintlich unabhängigen Prozessen hin und her senden, z. B. um Ergebnisse von einem (oder vielen) Arbeitsprozess (en) zurück zu einem "Haupt" -Prozess zu senden. (Es gibt eine gelegentliche Ausnahme, bei der jeder völlig unabhängig ist, aber es ist selten ... plus da ist die ganze Startsequenz selbst, gestartet von p.start() .) Also jede Process instance- p , in obigem Beispiel: Hat einen Kommunikationskanal zu seinem übergeordneten Ersteller und umgekehrt (es handelt sich um eine symmetrische Verbindung). Das Modul multiprocessing verwendet das Modul pickle , um Daten in Zeichenfolgen umzuwandeln - die gleichen Zeichenfolgen, die Sie in Dateien mit pickle.dump speichern können - und sendet die Daten über den Kanal, "abwärts" an Worker, um Argumente und dergleichen zu senden "aufwärts" von Arbeitern, um Ergebnisse zurückzusenden.

Wenn Sie schließlich alle Ergebnisse erzielt haben, beendet der Worker (indem er von der Funktion target= zurückkehrt) und teilt dem Elternteil mit, dass er fertig ist. Um sicherzustellen, dass alles geschlossen und bereinigt wird, sollte das übergeordnete Element p.join() aufrufen, um auf die "Ich bin fertig" -Nachricht des Benutzers zu warten (tatsächlich eine OS-Ebene exit auf Unix-ish-Systemen).

Das Beispiel ist ein wenig albern, da die zwei gedruckten Nachrichten im Grunde gar keine Zeit brauchen, so dass sie "zur gleichen Zeit" laufen, hat keinen messbaren Gewinn. Aber angenommen, anstatt nur hello zu drucken, sollten f die ersten 100.000 Stellen von π (3.14159 ...) berechnen. Sie könnten dann ein weiteres Process , p2 mit einem anderen Ziel g erzeugen, das die ersten 100.000 Stellen von e (2.71828 ...) berechnet. Diese würden unabhängig voneinander laufen. Die Eltern könnten dann p.join() und p2.join() aufrufen, um auf beide zu warten (oder noch mehr Arbeiter zu spawnen, um mehr Arbeit zu erledigen und mehr CPUs zu belegen, oder sogar erst einmal eine eigene Arbeit zu erledigen).

    
torek 11.08.2013, 08:09
quelle