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)
applyesiste ancora in Python2.7 sebbene non in Python3 e generalmente non viene più utilizzato. Al giorno d'oggi,
f(*args,**kwargs)
è preferito. I multiprocessing.Poolmoduli 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.applysi 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 AsyncResultrestituito 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_asyncmetodo 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_asyncsono 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.mapblocca 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.mapapplica la stessa funzione a molti argomenti. Tuttavia, a differenza Pool.apply_asyncdei 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.mape Pool.map_asyncè simile a quella di Pool.applye Pool.apply_async. I asynccomandi ritornano immediatamente, mentre i non- asynccomandi si bloccano. I asynccomandi hanno anche un callback.
Pool.maped Pool.applyè simile a decidere quando usare mapo applyin Python. Basta usare lo strumento adatto al lavoro. La decisione tra l'utilizzo della versione asyncnon e asyncdipende dalla richiesta della chiamata per bloccare il processo corrente e / o dalla possibilità di utilizzare la richiamata.
apply_asyncrestituisce un ApplyResultoggetto. Chiamata che ApplyResult's getmetodo restituirà il valore di ritorno della funzione associata (o rilancio mp.TimeoutErrorse i tempi-out. Di chiamata) Quindi, se si mettono le ApplyResults in un elenco ordinato, quindi chiamando i loro getmetodi restituirà i risultati nello stesso ordine. pool.mapTuttavia, potresti semplicemente utilizzare in questa situazione.
Per quanto riguarda applyvs map:
pool.apply(f, args): fviene 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.mape 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.imape 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.
Asynci 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.mapcui 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?