Sto cercando di elaborare il contenuto di un tarfile usando multiprocessing.Pool
. Sono in grado di utilizzare con successo l'implementazione ThreadPool all'interno del modulo multiprocessing, ma vorrei essere in grado di utilizzare processi anziché thread in quanto sarebbe probabilmente più veloce ed eliminare alcune modifiche apportate a Matplotlib per gestire l'ambiente multithread. Sto ottenendo un errore che ho il sospetto è legato a processi che non condividono lo spazio di indirizzi, ma non sono sicuro di come risolvere il problema:Come posso elaborare un tarfile con un pool di multiprocessing Python?
Traceback (most recent call last):
File "test_tarfile.py", line 32, in <module>
test_multiproc()
File "test_tarfile.py", line 24, in test_multiproc
pool.map(read_file, files)
File "/ldata/whitcomb/epd-7.1-2-rh5-x86_64/lib/python2.7/multiprocessing/pool.py", line 225, in map
return self.map_async(func, iterable, chunksize).get()
File "/ldata/whitcomb/epd-7.1-2-rh5-x86_64/lib/python2.7/multiprocessing/pool.py", line 522, in get
raise self._value
ValueError: I/O operation on closed file
Il programma attuale è più complicato, ma questo è un esempio di quello sto facendo che riproduce l'errore:
from multiprocessing.pool import ThreadPool, Pool
import StringIO
import tarfile
def write_tar():
tar = tarfile.open('test.tar', 'w')
contents = 'line1'
info = tarfile.TarInfo('file1.txt')
info.size = len(contents)
tar.addfile(info, StringIO.StringIO(contents))
tar.close()
def test_multithread():
tar = tarfile.open('test.tar')
files = [tar.extractfile(member) for member in tar.getmembers()]
pool = ThreadPool(processes=1)
pool.map(read_file, files)
tar.close()
def test_multiproc():
tar = tarfile.open('test.tar')
files = [tar.extractfile(member) for member in tar.getmembers()]
pool = Pool(processes=1)
pool.map(read_file, files)
tar.close()
def read_file(f):
print f.read()
write_tar()
test_multithread()
test_multiproc()
ho il sospetto che il qualcosa che non va quando l'oggetto TarInfo
viene passato l'altro processo, ma il genitore TarFile
non è, ma non sono sicuro come risolvere il problema in il caso multiprocesso. Posso farlo senza dover estrarre i file dal tarball e scriverli sul disco?
Supporto Windows: 'se nome == '__main__': test_multiproc()'. Non c'è fork in Windows, quindi il modulo viene importato nel nuovo processo inizialmente con il nome "__parents_main __", e quindi il nome viene cambiato in "__main __". Quindi puoi proteggere le dichiarazioni che non vuoi eseguire nei processi figli usando un blocco 'if'. – eryksun
Funziona, ma mi richiede di riaprire il tarfile in ogni processo. C'è qualche altro rimedio che consentirebbe l'accesso in sola lettura a un descrittore di file tra processi? –
Ho finito per impostare un flag per la pre-lettura dei dati prima che i processi multipli inizino. Grazie! –