it-swarm.com.de

multiprocessing.Pool: Wann wird apply, apply_async oder map verwendet?

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?

246
Phyo Arkar Lwin

Früher verwendeten Sie apply, um eine Funktion mit beliebigen Argumenten aufzurufen:

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 Modul multiprocessing.Pool Versucht, eine ähnliche Schnittstelle bereitzustellen.

Pool.apply Ist wie Python apply, außer dass der Funktionsaufruf in einem separaten Prozess ausgeführt wird. Pool.apply Blockiert, bis die Funktion abgeschlossen ist.

Pool.apply_async Ähnelt auch Pythons eingebautem apply, außer dass der Aufruf sofort zurückkommt, anstatt auf das Ergebnis zu warten. Ein AsyncResult Objekt wird zurückgegeben. Sie rufen die Methode get() auf, um das Ergebnis des Funktionsaufrufs abzurufen. Die Methode get() blockiert, bis die Funktion abgeschlossen ist. Somit ist pool.apply(func, args, kwargs) äquivalent zu pool.apply_async(func, args, kwargs).get().

Im Gegensatz zu Pool.apply Hat die Methode Pool.apply_async Auch einen Callback, der, falls angegeben, nach Beendigung der Funktion aufgerufen wird. Dies kann verwendet werden, anstatt get() aufzurufen.

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 __== '__main__':
    apply_async_with_callback()

kann zu einem Ergebnis führen wie

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

Beachten Sie, dass die Reihenfolge der Ergebnisse im Gegensatz zu pool.map Möglicherweise nicht der Reihenfolge entspricht, in der die Aufrufe von pool.apply_async Ausgeführt wurden.


Wenn Sie also eine Funktion in einem separaten Prozess ausführen müssen, aber möchten, dass der aktuelle Prozess block bis zur Rückkehr dieser Funktion lautet, verwenden Sie Pool.apply. Wie Pool.apply Blockiert Pool.map, Bis das vollständige Ergebnis zurückgegeben wird.

Wenn der Pool von Worker-Prozessen viele Funktionsaufrufe asynchron ausführen soll, verwenden Sie Pool.apply_async. Es wird nicht garantiert, dass die Reihenfolge der Ergebnisse mit der Reihenfolge der Aufrufe von Pool.apply_async Übereinstimmt.

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

Im Gegensatz dazu wendet Pool.map Dieselbe Funktion auf viele Argumente an. Im Gegensatz zu Pool.apply_async Werden die Ergebnisse jedoch in einer Reihenfolge zurückgegeben, die der Reihenfolge der Argumente entspricht.

369
unutbu

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 f(args) ausführen.

pool.map(f, iterable): Diese Methode zerlegt das Iterable in eine Reihe von Abschnitten, die es als separate Tasks an den Prozesspool sendet. So nutzen Sie alle Prozesse im Pool.

72
kakhkAtion