Ich habe keine klaren Beispiele mit Anwendungsfällen für Pool.apply , Pool.apply_async und Pool.map gesehen . Ich benutze hauptsächlich Pool.map
; Was sind die Vorteile anderer?
Ich habe keine klaren Beispiele mit Anwendungsfällen für Pool.apply , Pool.apply_async und Pool.map gesehen . Ich benutze hauptsächlich Pool.map
; Was sind die Vorteile anderer?
Antworten:
In den alten Tagen von Python würden Sie Folgendes 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. Die multiprocessing.Pool
Module versuchen, eine ähnliche Schnittstelle bereitzustellen.
Pool.apply
ist wie Python apply
, nur dass der Funktionsaufruf in einem separaten Prozess ausgeführt wird. Pool.apply
blockiert, bis die Funktion abgeschlossen ist.
Pool.apply_async
ist auch wie Pythons integriert apply
, außer dass der Aufruf sofort zurückkehrt, anstatt auf das Ergebnis zu warten. Ein AsyncResult
Objekt wird zurückgegeben. Sie rufen seine get()
Methode auf, um das Ergebnis des Funktionsaufrufs abzurufen. Die get()
Methode blockiert, bis die Funktion abgeschlossen ist. Somit pool.apply(func, args, kwargs)
ist äquivalent zu pool.apply_async(func, args, kwargs).get()
.
Im Gegensatz dazu Pool.apply
verfügt die Pool.apply_async
Methode auch über einen Rückruf, der, falls angegeben, nach Abschluss der Funktion aufgerufen wird. Dies kann verwendet werden, anstatt anzurufen get()
.
Beispielsweise:
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 ergeben wie
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Beachten Sie, dass pool.map
die Reihenfolge der Ergebnisse möglicherweise nicht der Reihenfolge entspricht, in der die pool.apply_async
Anrufe getätigt wurden.
Wenn Sie also eine Funktion in einem separaten Prozess ausführen müssen, der aktuelle Prozess jedoch blockiert werden soll, bis diese Funktion zurückkehrt, verwenden Sie Pool.apply
. Wie Pool.apply
, Pool.map
blockiert , bis das komplette Ergebnis zurückgegeben.
Wenn Sie möchten, dass der Pool von Arbeitsprozessen viele Funktionsaufrufe asynchron ausführt, verwenden Sie Pool.apply_async
. Es ist nicht garantiert, dass die Reihenfolge der Ergebnisse mit der Reihenfolge der Aufrufe von übereinstimmt Pool.apply_async
.
Beachten Sie auch, dass Sie eine Reihe verschiedener Funktionen mit aufrufen können Pool.apply_async
(nicht alle Aufrufe müssen dieselbe Funktion verwenden).
Im Gegensatz dazu wird Pool.map
dieselbe Funktion auf viele Argumente angewendet. Im Gegensatz dazu Pool.apply_async
werden die Ergebnisse jedoch in einer Reihenfolge zurückgegeben, die der Reihenfolge der Argumente entspricht.
Pool.map(func,iterable)
äquivalent zu ist Pool.map_async(func,iterable).get()
. Die Beziehung zwischen Pool.map
und Pool.map_async
ist also ähnlich der von Pool.apply
und Pool.apply_async
. Die async
Befehle kehren sofort zurück, während die Nichtbefehle async
blockieren. Die async
Befehle haben auch einen Rückruf.
Pool.map
und Pool.apply
ist ähnlich wie die Entscheidung, wann map
oder apply
in Python. Sie verwenden nur das Werkzeug, das zum Job passt. Die Entscheidung zwischen der Verwendung der async
und der Nichtversion async
hängt davon ab, ob der Anruf den aktuellen Prozess blockieren soll und / oder ob Sie den Rückruf verwenden möchten.
apply_async
Zurückgeben eines ApplyResult
Objekts. Der Aufruf , dass ApplyResult
‚s get
Methode wird die zugehörige Funktion Rückgabewert zurückgeben (oder zu erhöhen , mp.TimeoutError
wenn die Anrufzeiten-out.) Also , wenn Sie den setzen ApplyResult
s in einer geordneten Liste, dann ihre Aufruf get
Methoden werden die Ergebnisse in der gleichen Reihenfolge zurück. Sie können jedoch nur pool.map
in dieser Situation verwenden.
In Bezug auf apply
vs map
:
pool.apply(f, args)
: f
wird nur in EINEM der Arbeiter des Pools ausgeführt. Es wird also EINER der Prozesse im Pool ausgeführt f(args)
.
pool.map(f, iterable)
: Diese Methode zerlegt das Iterable in eine Reihe von Blöcken, die es als separate Aufgaben an den Prozesspool sendet. So nutzen Sie alle Prozesse im Pool.
apply_async()
8 Mal aufgerufen habe ? Wird es automatisch mit einer Warteschlange behandelt?
Hier ist eine Übersicht in Tabellenformat , um die Unterschiede zwischen dem zeigen Pool.apply
, Pool.apply_async
, Pool.map
und Pool.map_async
. Bei der Auswahl müssen Sie mehrere Argumente, Parallelität, Blockierung und Bestellung 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
Pool.imap
und Pool.imap_async
- faulere Version von map und map_async.
Pool.starmap
Methode, die der Map-Methode sehr ähnlich ist, außer dass mehrere Argumente akzeptiert werden.
Async
Methoden senden alle Prozesse auf einmal und rufen die Ergebnisse ab, sobald sie abgeschlossen sind. Verwenden Sie die Methode get, um die Ergebnisse zu erhalten.
Pool.map
(oder Pool.apply
) Methoden sind der in Python integrierten Map (oder Apply) sehr ähnlich. Sie blockieren den Hauptprozess, bis alle Prozesse abgeschlossen sind, und geben das Ergebnis zurück.
Wird für eine Liste von Jobs in einer Zeit aufgerufen
results = pool.map(func, [1, 2, 3])
Kann nur für einen Job aufgerufen werden
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Wird für eine Liste von Jobs in einer Zeit aufgerufen
pool.map_async(func, jobs, callback=collect_result)
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)
Ist eine Variante, pool.map
die mehrere Argumente unterstützt
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
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)
Die vollständige Dokumentation finden Sie hier: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
vorherapply_async_with_callback()
unter Windows geben?