Ich bin derzeit in einer Situation, in der ich Code wiederholt aufgerufen haben und versuchen, den Mehraufwand im Zusammenhang mit der Multiprozessverarbeitung zu reduzieren. Also, betrachten Sie das folgende Beispiel, die absichtlich keine „teure“ Berechnungen enthalten:Beseitigung von Overhead in Multiprocessing mit Pool
import multiprocessing as mp
def f(x):
# toy function
return x*x
if __name__ == '__main__':
for x in range(500):
pool = mp.Pool(processes=2)
print(pool.map(f, range(x, x + 50)))
pool.close()
pool.join() # necessary?
Dieser Code dauert 53 Sekunden im Vergleich zu 0,04 Sekunden für den sequentiellen Ansatz.
Erste Frage: muss ich wirklich pool.join() in diesem Fall aufrufen, wenn nur pool.map() jemals verwendet wird? Ich kann keine negativen Effekte finden, wenn ich es weglasse und die Laufzeit würde auf 4,8 Sekunden fallen. (Ich verstehe, dass das Auslassen von pool.close() nicht möglich ist, da wir dann Threads verlieren würden.)
Jetzt, während dies eine nette Verbesserung wäre, würde ich als erste Antwort wahrscheinlich "gut, nicht" t erst den Pool in der Schleife erstellen ". Ok, kein Problem, aber der parallelisiert Code lebt tatsächlich in einer Instanzmethode, so würde ich verwenden:
class MyObject:
def __init__(self):
self.pool = mp.Pool(processes=2)
def function(self, x):
print(self.pool.map(f, range(x, x + 50)))
if __name__ == '__main__':
my_object = MyObject()
for x in range(500):
my_object.function(x)
Das wäre meine favorisierte Lösung sein, wie es in einem ausgezeichneten 0,4 Sekunden läuft.
Zweite Frage: sollte ich pool.close()/pool.join() irgendwo explizit aufrufen (z. B. im Destruktor von MyObject) oder ist der aktuelle Code ausreichend? (Wenn es darauf ankommt: Es ist in Ordnung, anzunehmen, dass es in meinem Projekt nur wenige langlebige Instanzen von MyObject gibt.)
Sie verwenden don‘ t muss 'pool.join()' aufrufen, da es blockiert, bis alle Prozesse, die es begonnen hat, das iterierbare Argument zu verarbeiten, beendet sind ... und da du es nicht aufrufen wirst, ist es nicht nötig, die 'pool.close () 'entweder. – martineau
pool.close() ist notwendig, sonst bekomme ich eine "zu viele offene Dateien" Ausnahme (unter Linux) – sourceror
Gut zu wissen - und Sie haben einen Teil Ihrer eigenen Frage beantwortet. – martineau