Non ho visto esempi chiari con casi d'uso per Pool.apply , Pool.apply_async e Pool.map . Sto usando principalmente Pool.map
; quali sono i vantaggi degli altri?
Non ho visto esempi chiari con casi d'uso per Pool.apply , Pool.apply_async e Pool.map . Sto usando principalmente Pool.map
; quali sono i vantaggi degli altri?
Risposte:
Ai vecchi tempi di Python, per chiamare una funzione con argomenti arbitrari, avresti usato apply
:
apply(f,args,kwargs)
apply
esiste ancora in Python2.7 sebbene non in Python3 e generalmente non viene più utilizzato. Al giorno d'oggi,
f(*args,**kwargs)
è preferito. I multiprocessing.Pool
moduli tenta di fornire un'interfaccia simile.
Pool.apply
è come Python apply
, tranne per il fatto che la chiamata di funzione viene eseguita in un processo separato. Pool.apply
si blocca fino al completamento della funzione.
Pool.apply_async
è anche come integrato in Python apply
, tranne per il fatto che la chiamata ritorna immediatamente invece di attendere il risultato. Viene AsyncResult
restituito un oggetto. Si chiama il suo get()
metodo per recuperare il risultato della chiamata di funzione. Il get()
metodo si blocca fino al completamento della funzione. Pertanto, pool.apply(func, args, kwargs)
equivale a pool.apply_async(func, args, kwargs).get()
.
Al contrario Pool.apply
, il Pool.apply_async
metodo ha anche un callback che, se fornito, viene chiamato quando la funzione è completa. Questo può essere usato invece di chiamare get()
.
Per esempio:
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()
può dare un risultato come
[1, 0, 4, 9, 25, 16, 49, 36, 81, 64]
Si noti, a differenza pool.map
, l'ordine dei risultati potrebbe non corrispondere all'ordine in cui pool.apply_async
sono state effettuate le chiamate.
Pertanto, se è necessario eseguire una funzione in un processo separato, ma si desidera bloccare il processo corrente fino a quando tale funzione non viene restituita, utilizzare Pool.apply
. Ad esempio Pool.apply
, Pool.map
blocca fino a quando non viene restituito il risultato completo.
Se si desidera che il pool di processi di lavoro esegua molte chiamate di funzione in modo asincrono, utilizzare Pool.apply_async
. L' ordine dei risultati non è garantito essere uguale all'ordine delle chiamate a Pool.apply_async
.
Si noti inoltre che è possibile chiamare diverse funzioni con Pool.apply_async
(non tutte le chiamate devono utilizzare la stessa funzione).
Al contrario, Pool.map
applica la stessa funzione a molti argomenti. Tuttavia, a differenza Pool.apply_async
dei risultati, i risultati vengono restituiti in un ordine corrispondente all'ordine degli argomenti.
Pool.map(func,iterable)
è equivalente a Pool.map_async(func,iterable).get()
. Quindi la relazione tra Pool.map
e Pool.map_async
è simile a quella di Pool.apply
e Pool.apply_async
. I async
comandi ritornano immediatamente, mentre i non- async
comandi si bloccano. I async
comandi hanno anche un callback.
Pool.map
ed Pool.apply
è simile a decidere quando usare map
o apply
in Python. Basta usare lo strumento adatto al lavoro. La decisione tra l'utilizzo della versione async
non e async
dipende dalla richiesta della chiamata per bloccare il processo corrente e / o dalla possibilità di utilizzare la richiamata.
apply_async
restituisce un ApplyResult
oggetto. Chiamata che ApplyResult
's get
metodo restituirà il valore di ritorno della funzione associata (o rilancio mp.TimeoutError
se i tempi-out. Di chiamata) Quindi, se si mettono le ApplyResult
s in un elenco ordinato, quindi chiamando i loro get
metodi restituirà i risultati nello stesso ordine. pool.map
Tuttavia, potresti semplicemente utilizzare in questa situazione.
Per quanto riguarda apply
vs map
:
pool.apply(f, args)
: f
viene eseguito solo in UNO dei lavoratori della piscina. Quindi, uno dei processi nel pool verrà eseguito f(args)
.
pool.map(f, iterable)
: Questo metodo taglia l'iterabile in un numero di blocchi che invia al pool di processi come attività separate. Quindi approfitti di tutti i processi nel pool.
apply_async()
8 volte? Lo gestirà automaticamente con una coda?
Ecco una panoramica in un formato tabella per mostrare le differenze tra Pool.apply
, Pool.apply_async
, Pool.map
e Pool.map_async
. Quando ne scegli uno, devi prendere in considerazione multi-arg, concorrenza, blocco e ordini:
| 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
e Pool.imap_async
- versione più pigra di map e map_async.
Pool.starmap
metodo, molto simile al metodo cartografico oltre all'accettazione di più argomenti.
Async
i metodi inviano tutti i processi contemporaneamente e recuperano i risultati al termine. Utilizzare il metodo get per ottenere i risultati.
Pool.map
(o Pool.apply
) i metodi sono molto simili alla mappa (o applica) integrata di Python. Bloccano il processo principale fino al completamento di tutti i processi e restituiscono il risultato.
Viene chiamato per un elenco di lavori in una volta
results = pool.map(func, [1, 2, 3])
Può essere chiamato solo per un lavoro
for x, y in [[1, 1], [2, 2]]:
results.append(pool.apply(func, (x, y)))
def collect_result(result):
results.append(result)
Viene chiamato per un elenco di lavori in una volta
pool.map_async(func, jobs, callback=collect_result)
Può essere chiamato solo per un lavoro ed esegue un lavoro in background in parallelo
for x, y in [[1, 1], [2, 2]]:
pool.apply_async(worker, (x, y), callback=collect_result)
È una variante di pool.map
cui supporta più argomenti
pool.starmap(func, [(1, 1), (2, 1), (3, 1)])
Una combinazione di starmap () e map_async () che scorre su iterabili di iterabili e chiama funzioni con iterabili decompressi. Restituisce un oggetto risultato.
pool.starmap_async(calculate_worker, [(1, 1), (2, 1), (3, 1)], callback=collect_result)
Trova la documentazione completa qui: https://docs.python.org/3/library/multiprocessing.html
if __name__=="__main__"
primaapply_async_with_callback()
su Windows?