Sto provando a eseguire qualche codice Python su diversi file in parallelo. Il costrutto è fondamentalmente:Il pool di multiprocessing Python si blocca al join?
def process_file(filename, foo, bar, baz=biz):
# do stuff that may fail and cause exception
if __name__ == '__main__':
# setup code setting parameters foo, bar, and biz
psize = multiprocessing.cpu_count()*2
pool = multiprocessing.Pool(processes=psize)
map(lambda x: pool.apply_async(process_file, (x, foo, bar), dict(baz=biz)), sys.argv[1:])
pool.close()
pool.join()
ho usato in precedenza pool.map di fare qualcosa di simile e ha funzionato grande, ma io non riesco a utilizzare che qui perché pool.map non (sembra) permettetemi di passare argomenti extra (e usare lambda per farlo non funzionerà perché lambda non può essere marshalling).
Così ora sto cercando di far funzionare le cose usando apply_async() direttamente. Il mio problema è che il codice sembra bloccarsi e non uscire mai. Alcuni file non riescono con un'eccezione, ma non vedo perché ciò che potrebbe causare un errore/hang del join? È interessante notare che se nessuno dei file fallisce con un'eccezione, esce in modo pulito.
Cosa mi manca?
Edit: Quando la funzione (e quindi un lavoratore) non riesce, vedo questa eccezione:
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 376, in _handle_results
task = get()
TypeError: ('__init__() takes at least 3 arguments (1 given)', <class 'subprocess.CalledProcessError'>,())
se vedo anche uno solo di questi, il processo padre processo si blocca per sempre, non raccogliendo i figli e in uscita .
Il tuo codice sembra funzionare correttamente, anche se lancio eccezioni casuali in "file_processo". Quindi forse ha a che fare con ciò che stai facendo in 'process_file' che sta causando i problemi. – robertklep
Huh. quale versione di Python? Sono a 2,7. process_file nel programma reale è piuttosto complesso, facendo un uso pesante di PIL, NetworkX, poly2tri e altre librerie. Conosco almeno 2 posizioni in cui ho riscontrato bug che possono causare eccezioni in alcuni casi, ma devo semplicemente ignorare quegli errori e andare avanti. Sono perplesso sul motivo per cui non uscirebbe mai per me, ma lavorare per voi. – clemej
2.7.2, questo è quello che ho provato con: https://gist.github.com/robertklep/5125319 – robertklep