Ich habe keine klaren Beispiele mit Anwendungsfällen für gesehen Pool.apply, Pool.apply_async und Pool.map. Ich benutze hauptsächlich Pool.map
; Was sind die Vorteile anderer?
multiprocessing.Pool: Wann sollte apply, apply_async oder map verwendet werden?
Phyo Arkar Lwin
unutbu
In den alten Tagen von Python würden Sie verwenden, um eine Funktion mit beliebigen Argumenten aufzurufen apply
:
apply(f,args,kwargs)
apply
existiert immer noch in Python2.7, jedoch nicht in Python3, und wird im Allgemeinen nicht mehr verwendet. Heutzutage,
f(*args,**kwargs)
Ist bevorzugt. Das multiprocessing.Pool
Module versucht, eine ähnliche Schnittstelle bereitzustellen.
Pool.apply
ist wie Python apply
außer dass der Funktionsaufruf in einem separaten Prozess durchgeführt wird. Pool.apply
blockiert, bis die Funktion abgeschlossen ist.
Pool.apply_async
ist auch wie in Python eingebaut apply
, außer dass der Aufruf sofort zurückkehrt, anstatt auf das Ergebnis zu warten. Ein AsyncResult
Objekt wird zurückgegeben. Du nennst es get()
-Methode, um das Ergebnis des Funktionsaufrufs abzurufen. Das get()
Methode blockiert, bis die Funktion abgeschlossen ist. Daher, pool.apply(func, args, kwargs)
ist äquivalent zu pool.apply_async(func, args, kwargs).get()
.
Im Kontrast zu Pool.apply
das Pool.apply_async
-Methode hat auch einen Rückruf, der, falls angegeben, aufgerufen wird, wenn die Funktion abgeschlossen ist. Dies kann anstelle des Anrufs verwendet werden get()
.
Zum Beispiel:
import multiprocessing as mp
import time
def foo_pool(x):
time.sleep(2)
return x*x
result_list = []
def log_result(result):
# This is called whenever foo_pool(i) returns a result.
# result_list is modified only by the main process, not the pool workers.
result_list.append(result)
def apply_async_with_callback():
pool = mp.Pool()
for i in range(10):
pool.apply_async(foo_pool, args = (i, ), callback = log_result)
pool.close()
pool.join()
print(result_list)
if __name__ == '__main__':
apply_async_with_callback()
kann ein Ergebnis wie z
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Beachten Sie, anders pool.map
entspricht die Reihenfolge der Ergebnisse möglicherweise nicht der Reihenfolge, in der die pool.apply_async
Anrufe wurden getätigt.
Also, wenn Sie eine Funktion in einem separaten Prozess ausführen müssen, aber möchten, dass der aktuelle Prozess dies tut Block bis diese Funktion zurückkehrt, verwenden Pool.apply
. Wie Pool.apply
, Pool.map
Blöcke, bis das vollständige Ergebnis zurückgegeben wird.
Wenn Sie möchten, dass der Pool von Arbeitsprozessen viele Funktionsaufrufe asynchron ausführt, verwenden Sie Pool.apply_async
. Das bestellen der Ergebnisse stimmt nicht garantiert mit der Reihenfolge der Aufrufe überein Pool.apply_async
.
Beachten Sie auch, dass Sie mehrere anrufen können anders funktioniert mit Pool.apply_async
(Nicht alle Anrufe müssen dieselbe Funktion verwenden).
Im Gegensatz, Pool.map
wendet dieselbe Funktion auf viele Argumente an. Allerdings im Gegensatz Pool.apply_async
werden die Ergebnisse in einer Reihenfolge zurückgegeben, die der Reihenfolge der Argumente entspricht.
-
Sollte da sein
if __name__=="__main__"
Vorapply_async_with_callback()
unter Windows?– jfs
16. Dezember 2011 um 12:38 Uhr
-
Einblick multiprocessing/pool.py und das wirst du sehen
Pool.map(func,iterable)
ist äquivalent zuPool.map_async(func,iterable).get()
. Also das Verhältnis zwischenPool.map
undPool.map_async
ist ähnlich wie beiPool.apply
undPool.apply_async
. Dasasync
Befehle werden sofort zurückgegeben, während die nichtasync
Befehle blockieren. Dasasync
Befehle haben auch einen Callback.– unutbu
17. Dezember 2011 um 11:38 Uhr
-
Entscheidung zwischen der Verwendung
Pool.map
undPool.apply
ist ähnlich wie die Entscheidung, wann verwendet werden sollmap
oderapply
in Python. Sie verwenden einfach das Werkzeug, das zum Job passt. Entscheiden Sie sich zwischen der Verwendung derasync
und nicht-async
Version hängt davon ab, ob Sie möchten, dass der Aufruf den aktuellen Prozess blockiert und/oder ob Sie den Rückruf verwenden möchten.– unutbu
17. Dezember 2011 um 11:39 Uhr
-
@falsePockets: Ja. Jeder Anruf an
apply_async
gibt ein zurückApplyResult
Objekt. Das nennenApplyResult
‘sget
-Methode gibt den Rückgabewert der zugeordneten Funktion zurück (oder raisemp.TimeoutError
wenn der Anruf abläuft.) Also, wenn Sie die setzenApplyResult
s in einer geordneten Liste, dann Aufruf ihrerget
Methoden geben die Ergebnisse in der gleichen Reihenfolge zurück. Du könntest einfach verwendenpool.map
in dieser Situation jedoch.– unutbu
22. Mai 2017 um 10:11 Uhr
-
@galactica: Jedes Mal, wenn die Worker-Funktion erfolgreich beendet wird (ohne eine Ausnahme auszulösen), wird die Callback-Funktion aufgerufen im Hauptprozess. Die Worker-Funktionen stellen Rückgabewerte in eine Warteschlange, und die
pool._result_handler
Thread im Hauptprozess verarbeitet die zurückgegebenen Werte einzeln und übergibt den zurückgegebenen Wert an die Callback-Funktion. So ist garantiert, dass die Callback-Funktion einmal für jeden zurückgegebenen Wert aufgerufen wird, und es gibt hier kein Parallelitätsproblem, da der Callback sequentiell von einem einzelnen Thread im Hauptprozess aufgerufen wird.– unutbu
29. Juli 2019 um 22:46 Uhr
René B.
Hier ist eine Übersicht in Tabellenform, um die Unterschiede aufzuzeigen Pool.apply
, Pool.apply_async
, Pool.map
und Pool.map_async
. Bei der Auswahl müssen Sie Multi-Args, Parallelität, Blockierung und Reihenfolge berücksichtigen:
| Multi-args Concurrence Blocking Ordered-results
---------------------------------------------------------------------
Pool.map | no yes yes yes
Pool.map_async | no yes no yes
Pool.apply | yes no yes no
Pool.apply_async | yes yes no no
Pool.starmap | yes yes yes yes
Pool.starmap_async| yes yes no no
Anmerkungen:
-
Pool.imap
undPool.imap_async
– faulere Version von map und map_async. -
Pool.starmap
Methode, die der Kartenmethode sehr ähnlich ist, abgesehen davon, dass sie mehrere Argumente akzeptiert. -
Async
Methoden übermitteln alle Prozesse auf einmal und rufen die Ergebnisse ab, sobald sie abgeschlossen sind. Verwenden Sie die get-Methode, um die Ergebnisse zu erhalten. -
Pool.map
(oderPool.apply
)-Methoden sind der in Python integrierten map(or apply) sehr ähnlich. Sie blockieren den Hauptprozess, bis alle Prozesse abgeschlossen sind, und geben das Ergebnis zurück.
Beispiele:
Karte
Wird für eine Liste von Jobs auf einmal aufgerufen
results = pool.map(func, [1, 2, 3])
anwenden
Kann nur für einen Job angerufen werden
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
map_async
Wird für eine Liste von Jobs auf einmal aufgerufen
pool.map_async(func, jobs, callback=collect_result)
apply_async
Kann nur für einen Job aufgerufen werden und führt parallel einen Job im Hintergrund aus
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
Sternenkarte
Ist eine Variante von pool.map
die mehrere Argumente unterstützen
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
starmap_async
Eine Kombination aus starmap() und map_async(), die über Iterable von Iterables iteriert und func mit den entpackten Iterables aufruft. Gibt ein Ergebnisobjekt zurück.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Bezug:
Vollständige Dokumentation finden Sie hier: https://docs.python.org/3/library/multiprocessing.html
-
Pool.starmap() blockiert
– Alan Evangelista
20. März 2020 um 0:43 Uhr
-
Ich mag diese Antwort, +1
– Shayan Amani
13. April 2021 um 20:50 Uhr
-
Wenn apply keine Zustimmung hat, was ist dann sein Sinn? verwenden?
– Ritwik
2. Mai 2021 um 19:37 Uhr
-
Eine Tabelle/ein Bild sagt mehr als tausend Worte, ich komme immer wieder auf diese Antwort zurück, um die gewünschte Funktion auszuwählen.
– Luchao-Qi
2. Mai um 18:52 Uhr
kakhkAtion
Bezüglich apply
vs map
:
pool.apply(f, args)
: f
wird nur in EINEM der Worker des Pools ausgeführt. Einer der Prozesse im Pool wird also ausgeführt f(args)
.
pool.map(f, iterable)
Hinweis: Diese Methode zerlegt das Iterable in eine Reihe von Chunks, die es als separate Tasks an den Prozesspool übermittelt. So nutzen Sie alle Prozesse im Pool.
-
Was ist, wenn das Iterable ein Generator ist?
– RustyShackleford
21. Juni 2017 um 19:36 Uhr
-
Hm… Gute Frage. Um ehrlich zu sein, habe ich noch nie Pools mit Generatoren verwendet, aber dieser Thread könnte hilfreich sein: stackoverflow.com/questions/5318936/…
– kakhkAtion
21. Juni 2017 um 20:10 Uhr
-
@kakhkAtion In Bezug auf gelten, wenn nur einer der Arbeiter die Funktion ausführt, was tun die restlichen Arbeiter? Muss ich mich mehrmals bewerben, damit der Rest der Mitarbeiter eine Aufgabe erledigt?
– Moondra
27. Juli 2017 um 17:33 Uhr
-
WAHR. Werfen Sie auch einen Blick auf pool.apply_async, wenn Sie Arbeiter asynchron zu Mittag essen möchten. “pool_apply blockiert, bis das Ergebnis fertig ist, also ist apply_async() besser geeignet, um parallel zu arbeiten”
– kakhkAtion
27. Juli 2017 um 18:50 Uhr
-
Was passiert, wenn ich doch 4 Prozesse angerufen habe
apply_async()
8 mal? Wird es automatisch mit einer Warteschlange behandelt?– Saravanabalagi Ramachandran
23. Dezember 2019 um 14:19 Uhr