[英]How can I process a tarfile with a Python multiprocessing pool?
我正在尝试使用multiprocessing.Pool
tarfile的内容。 我能够在多处理模块中成功使用ThreadPool实现,但是希望能够使用进程而不是线程,因为这样可能会更快,并且消除了Matplotlib处理多线程环境所做的一些更改。 我收到一个我怀疑与进程不共享地址空间有关的错误,但是我不确定如何解决:
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
实际程序更复杂,但这是我正在做的一个示例,该示例再现了该错误:
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()
我怀疑将TarInfo
对象传递给另一个进程时TarFile
,但父TarFile
没有,但是我不确定在多进程情况下如何解决。 我可以这样做而不必从压缩包中提取文件并将它们写入磁盘吗?
您没有将TarInfo
对象传递给另一个进程,而是将tar.extractfile(member)
的结果传递给了另一个member
为TarInfo
对象的进程。 extractfile(...)
方法返回一个类似文件的对象,该对象除其他外具有一个read()
方法,该方法可对您使用tar = tarfile.open('test.tar')
打开的原始tar文件进行操作。
但是,您不能在另一个过程中使用一个过程中打开的文件,而必须重新打开该文件。 我用以下代码替换了您的test_multiproc()
:
def test_multiproc():
tar = tarfile.open('test.tar')
files = [name for name in tar.getnames()]
pool = Pool(processes=1)
result = pool.map(read_file2, files)
tar.close()
并添加以下内容:
def read_file2(name):
t2 = tarfile.open('test.tar')
print t2.extractfile(name).read()
t2.close()
并能够使您的代码正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.