2016-07-08 29 views
15

Sto usando 'multiprocess.Pool.imap_unordered' come segueQuando dovremmo chiamare multiprocessing.Pool.join?

from multiprocessing import Pool 
pool = Pool() 
for mapped_result in pool.imap_unordered(mapping_func, args_iter): 
    do some additional processing on mapped_result 

Devo chiamare pool.close o pool.join dopo il ciclo for?

+0

In genere chiamo 'pool.join()' poi 'pool.close()' una volta che ho avviato tutti i thread del pool, ma non ho provato a usare 'pool.imap_unordered()' come iterabile. – Bamcclur

+0

qual è il punto di chiamata join o close? Non li ho chiamati e il mio codice sembra funzionare correttamente. Tuttavia, sono preoccupato che non chiamare quelli risulterebbe in processi di zombie o altre cose sottili. –

risposta

26

No, non è così, ma probabilmente è una buona idea se non si utilizzerà più la piscina.

Motivi per chiamare pool.close o pool.join sono ben detto da Tim Peters in this SO post:

Per quanto riguarda Pool.close(), si dovrebbe chiamare che quando - e solo quando - si è mai andare a presentare più lavoro per l'istanza di Pool. Quindi Pool.close() viene in genere chiamato quando la parte parallelizable del programma principale è terminata. Quindi i processi di lavoro terminano quando tutto il lavoro già assegnato è stato completato.

È anche una pratica eccellente chiamare Pool.join() per attendere il termine dei processi di lavoro. Tra l'altro, spesso non c'è un buon modo di riportare le eccezioni nel codice in parallelo (le eccezioni si verificano in un contesto solo vagamente correlato a ciò che sta facendo il programma principale) e Pool.join() fornisce un punto di sincronizzazione che può segnalare alcune eccezioni che si sono verificate in processi di lavoro che altrimenti non vedresti mai.

+3

è meglio chiamare uno prima dell'altro? – RSHAP

+2

Sembra che alla gente piaccia chiamare 'pool.close()' e 'pool.join()' secondo. Ciò consente di aggiungere lavoro tra 'pool.close()' e 'pool.join()' che non ha bisogno di attendere il completamento dell'esecuzione del pool. – Bamcclur

+0

Giusto per aggiungere al commento di @ Bamcclur - non è solo una buona idea chiamare prima 'pool.close(), in realtà è obbligatorio. Da [i documenti] (https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool): Si deve chiamare 'close()' o 'terminate()' prima di usare ' join() '. – Bogd

3

Ho avuto lo stesso problema memoria, come Memory usage keep growing with Python's multiprocessing.pool quando non ho usato pool.close() e pool.join() quando si utilizza pool.map() con una funzione che calcola Levenshtein distanza. La funzione ha funzionato bene, ma non è stata raccolta in modo corretto su una macchina Win7 64 e l'utilizzo della memoria ha continuato a crescere senza controllo ogni volta che veniva richiamata la funzione fino a quando non veniva interrotto l'intero sistema operativo. Ecco il codice che ha risolto la perdita:

stringList = [] 
for possible_string in stringArray: 
    stringList.append((searchString,possible_string)) 

pool = Pool(5) 
results = pool.map(myLevenshteinFunction, stringList) 
pool.close() 
pool.join() 

Dopo aver chiuso e unito la piscina, la perdita di memoria è scomparsa.