Dies (enorm vereinfachtes Beispiel) funktioniert gut (Python 2.6.6, Debian Squeeze):Alternative Nutzungsmuster für Python-Multiprozessing, die Vermehrung des globalen Zustands vermeiden?
from multiprocessing import Pool
import numpy as np
src=None
def process(row):
return np.sum(src[row])
def main():
global src
src=np.ones((100,100))
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
jedoch nach Jahren der globaler Zustand schlecht gelehrt !!!, alle meine Instinkte sagen mir etwas näher an wirklich, ich würde wirklich lieber schreiben:
from multiprocessing import Pool
import numpy as np
def main():
src=np.ones((100,100))
def process(row):
return np.sum(src[row])
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
aber das ist natürlich nicht funktioniert (auflegt nicht in der Lage, etwas beizen).
Das Beispiel hier ist trivial, aber wenn Sie mehrere "Prozess" -Funktionen hinzufügen, und jede davon ist abhängig von mehreren zusätzlichen Eingaben ... Nun, es erinnert ein bisschen an etwas in BASIC vor 30 Jahren geschrieben . Der Versuch, Klassen zu verwenden, um zumindest den Zustand mit den entsprechenden Funktionen zu aggregieren, scheint eine naheliegende Lösung zu sein, aber in der Praxis ist es doesn't seem to be that easy.
Gibt es einige empfohlene Muster oder Stile für die Verwendung von multiprocessing.pool, die die Verbreitung des globalen Zustands zur Unterstützung jeder Funktion, die ich parallel abbilden möchte, vermeiden?
Wie gehen erfahrene "Multiprocessing-Profis" damit um?
aktualisieren: Beachten Sie, dass ich bei der Verarbeitung viel größeren Arrays tatsächlich interessiert bin, so Variationen der oben dem src
Beize jeden Anruf/Iteration sind nicht annähernd so gut wie diejenigen es welche Gabel in die Arbeitsprozesse Becken.
Ich bin kein erfahrener Profi oder etwas Multiprozessing, aber lassen Sie mich Ihnen fragen, warum können Sie nicht mach einfach pool.map (process, product ([src], range (100))) und ändere die Prozessfunktion um beide Variablen als args zu akzeptieren? Ist das auch sehr ineffizient? – luke14free
@ luke14free: Ja, das würde das src-Array bei jedem Aufruf ersetzen, und ich bin eigentlich an viel größeren Daten/Arrays interessiert als die im obigen Beispielcode, also nicht ideal. Mit dem Prozesspool wird der Zustand, der an dem Punkt eingerichtet wird, an dem der Pool erstellt wird, in die Worker-Prozesse gespalten und steht für sie zur Verfügung, um "kostenlos" zu lesen. Die Idee würde helfen, zu vermeiden, dass kleinere "Kontrollvariablen" (z. B. Flags) in globale Variablen gesetzt werden, danke. – timday