410 Stimmen

multiprocessing.Pool: Wann ist apply, apply_async oder map zu verwenden?

Ich habe keine eindeutigen Beispiele mit Anwendungsfällen gesehen für Pool.anwenden , Pool.apply_async y Pool.map . Ich verwende hauptsächlich Pool.map Was sind die Vorteile der anderen?

563voto

unutbu Punkte 769083

In den alten Tagen von Python, um eine Funktion mit beliebigen Argumenten aufzurufen, würden Sie verwenden apply :

apply(f,args,kwargs)

apply existiert noch in Python2.7, aber nicht in Python3, und wird im Allgemeinen nicht mehr verwendet. Heutzutage,

f(*args,**kwargs)

bevorzugt wird. Die Website multiprocessing.Pool Module versucht, eine ähnliche Schnittstelle zu bieten.

Pool.apply ist wie Python apply mit dem Unterschied, 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 eingebautes apply mit dem Unterschied, dass der Aufruf sofort zurückkehrt, anstatt auf das Ergebnis zu warten. Eine AsyncResult Objekt zurückgegeben wird. Sie rufen dessen get() Methode, um das Ergebnis des Funktionsaufrufs abzurufen. Die get() Methode blockiert, bis die Funktion abgeschlossen ist. So, pool.apply(func, args, kwargs) ist gleichbedeutend mit pool.apply_async(func, args, kwargs).get() .

Im Gegensatz zu Pool.apply die Pool.apply_async Methode hat auch einen Callback, der, falls angegeben, aufgerufen wird, wenn die Funktion beendet ist. Dies kann anstelle des Aufrufs von 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 folgt ergeben

[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]

Beachten Sie, dass im Gegensatz zu pool.map Die Reihenfolge der Ergebnisse entspricht unter Umständen nicht der Reihenfolge, in der die pool.apply_async Anrufe wurden getätigt.


Wenn Sie also eine Funktion in einem separaten Prozess ausführen müssen, aber möchten, dass der aktuelle Prozess Block bis diese Funktion zurückkehrt, verwenden Sie Pool.apply . Wie Pool.apply , Pool.map blockiert, 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 . Die Bestellung der Ergebnisse ist nicht garantiert, dass sie mit der Reihenfolge der Aufrufe von Pool.apply_async .

Beachten Sie auch, dass Sie eine Reihe von Funktionen aufrufen können verschiedene Funktionen mit Pool.apply_async (nicht alle Aufrufe müssen dieselbe Funktion verwenden).

Im Gegensatz dazu, Pool.map wendet die gleiche Funktion auf viele Argumente an. Doch im Gegensatz zu Pool.apply_async werden die Ergebnisse in einer Reihenfolge zurückgegeben, die der Reihenfolge der Argumente entspricht.

189voto

Rene B. Punkte 5753

Hier ein tabellarischer Überblick, um die Unterschiede zwischen Pool.apply , Pool.apply_async , Pool.map y Pool.map_async . Wenn Sie sich für eine entscheiden, müssen Sie Multi-Args, Gleichzeitigkeit, 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 y Pool.imap_async - eine langsamere Version von map und map_async.

  • Pool.starmap Methode, die der map-Methode sehr ähnlich ist, außer dass sie mehrere Argumente akzeptiert.

  • 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 den in Python eingebauten map (oder 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 Aufträgen in einer Zeit aufgerufen

results = pool.map(func, [1, 2, 3])

anwenden.

Kann nur für einen Auftrag eingesetzt 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 Aufträgen in einer Zeit aufgerufen

pool.map_async(func, jobs, callback=collect_result)

apply_async

Kann nur für einen Job aufgerufen werden und führt einen Job im Hintergrund parallel aus

for x, y in [[1, 1], [2, 2]]:
    pool.apply_async(worker, (x, y), callback=collect_result)

starmap

Ist eine Variante von pool.map die mehrere Argumente unterstützen

pool.starmap(func, [(1, 1), (2, 1), (3, 1)])

starmap_async

Eine Kombination von starmap() und map_async(), die über eine 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)

Referenz:

Die vollständige Dokumentation finden Sie hier: https://docs.python.org/3/library/multiprocessing.html

90voto

kakhkAtion Punkte 2134

Betreffend apply gegen map :

pool.apply(f, args) : f wird nur in EINEM der Arbeiter des Pools ausgeführt. Einer der Prozesse im Pool wird also ausgeführt f(args) .

pool.map(f, iterable) : Diese Methode zerlegt die iterierbare Datei in eine Reihe von Teilen, die sie als separate Aufgaben an den Prozess-Pool übergibt. So können Sie alle Prozesse im Pool nutzen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X