multiprocessing.Pool mit einer globalen Variablen
Ich bin mit dem Pool Klasse aus-python-multiprocessing-Bibliothek ein Programm schreiben, die ausgeführt wird, auf einem HPC-cluster.
Hier ist eine Abstraktion von dem, was ich zu tun versuche:
def myFunction(x):
# myObject is a global variable in this case
return myFunction2(x, myObject)
def myFunction2(x,myObject):
myObject.modify() # here I am calling some method that changes myObject
return myObject.f(x)
poolVar = Pool()
argsArray = [ARGS ARRAY GOES HERE]
output = poolVar.map(myFunction, argsArray)
Die Funktion f(x) in a enthalten ist *.also Datei, D. H., es wird der Aufruf einer C-Funktion.
Das problem, das ich habe ist, dass der Wert der output-variable unterscheidet sich jedes mal, wenn ich aus meinem Programm (obwohl die Funktion myObject.f() ist eine deterministische Funktion). (Wenn ich nur eins haben kann, wird dann die output-variable ist gleich, jedes mal wenn ich das Programm ausführen.)
Ich habe versucht, erstellen Sie das Objekt, anstatt es zu speichern als Globale variable:
def myFunction(x):
myObject = createObject()
return myFunction2(x, myObject)
Jedoch in meinem Programm die Objekt-Erstellung ist teuer, und so ist es viel einfacher zu erstellen myObject einmal und dann ändern Sie es jedes mal, wenn ich rufe myFunction2(). Damit möchte ich nicht erstellen, das Objekt jedes mal.
Haben Sie irgendwelche Tipps? Ich bin sehr neu in der parallelen Programmierung, so konnte ich gehen über diese alle falsch. Ich beschloss, den Pool zu benutzen Klasse, da wollte ich mit etwas einfachem beginnen. Aber ich bin bereit, zu versuchen, einen besseren Weg, es zu tun.
- Könnten Sie dieses Problem beheben Programm zu sein, die läuft? Das erklären der Funktionen, nachdem Sie versuchen, Sie zu benutzen wird nicht funktionieren in Python (und relevant sein könnten, zu deinem problem)
- Ist
myObject.modify()
idempotent? Das ist, können Sie es nennen eine beliebige Anzahl von Zeiten, ohne zu verändern, was es tut (wie einreset()
- Funktion)? Wenn ja, ist Ihr code sollte funktionieren. Wenn nicht, wirst du Probleme haben, weil die unterschiedlichen Prozesse, wird jede änderung Ihrer eigenen Kopien des Objekts getrennt von einander, und so können Sie duplizierte Werte über Prozesse. - Ja, myObject.ändern Sie() ist idempotent.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Prozesse sind nicht threads! Sie nicht einfach ersetzen
Thread
mitProcess
und erwarten, dass alle die gleiche Arbeit.Process
es tun nicht Speicher freigeben, was bedeutet, dass die globalen Variablen sind kopiert, damit Ihren Wert in der ursprünglichen Prozess nicht ändern.Wenn Sie möchten, um die Verwendung von shared memory zwischen Prozessen, dann müssen Sie die
multiprocessing
's Daten-Typen, wieValue
,Array
oder verwenden Sie denManager
zum erstellen von freigegebenen Listen etc.Insbesondere Sie von Interesse sein könnten in der
Manager.register
Methode, die erlaubt dieManager
zum erstellen von freigegebenen benutzerdefinierten Objekte(obwohl Sie müssen picklable).Aber ich bin mir nicht sicher, ob dies wird die Leistung verbessern. Da alle Kommunikation zwischen Prozessen erfordert Beizen und marinieren dauert in der Regel mehr Zeit dann einfach das Objekt instanziiert.
Beachten Sie, dass Sie tun können, einige die Initialisierung der Arbeitsprozesse bestehen der
initializer
undinitargs
argument bei der Erstellung desPool
.Z. B. in seiner einfachsten form, erstellen Sie eine Globale variable in den Arbeitsprozess:
Als:
Dann die worker-Funktionen verwenden können, die
data
Globale variable ohne sorgen.Stil Hinweis: Nie den Namen einer built-in für die Variablen/Module. In Ihrem Fall
object
ist ein built-in. Sonst wirst du am Ende mit unerwarteten Fehlern, die möglicherweise obskure und schwer aufzuspüren.