8

を使用してtarfileの内容を処理しようとしていますmultiprocessing.Pool。マルチプロセッシングモジュール内で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はそうではありませんが、マルチプロセスの場合にそれを修正する方法がわかりません。tarballからファイルを抽出してディスクに書き込むことなくこれを行うことはできますか?

4

1 に答える 1

7

オブジェクトを他のプロセスに渡すのではなく、オブジェクトである他のプロセスTarInfoに結果を渡します。このメソッドは、とりわけ、 で開いた元の tar ファイルに対して動作するメソッドを持つファイルのようなオブジェクトを返します。tar.extractfile(member)memberTarInfoextractfile(...)read()tar = tarfile.open('test.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()

コードを機能させることができました。

于 2011-11-23T23:40:55.347 に答える