2011-11-23 8 views
5

multiprocessing.Poolを使用して、tarファイルの内容を処理しようとしています。私は、マルチプロセッシングモジュール内でThreadPoolの実装をうまく使用することができますが、スレッドの代わりにプロセスを使用できるようにしたいのですが、Matplotlibがマルチスレッド環境を処理するためのいくつかの変更を排除します。私は、アドレス空間を共有していないプロセスに関係している疑いがあるエラーを取得していますが、私はそれを修正するかどうかはわかりません。Pythonマルチプロセッシングプールでtarファイルを処理するにはどうしたらいいですか?

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からファイルを抽出してディスクに書き込まなくても、これを実行できますか?

答えて

5

TarInfoオブジェクトを他のプロセスに渡すのではなく、tar.extractfile(member)の結果をmemberTarInfoオブジェクトである他のプロセスに渡しています。 extractfile(...)メソッドは、tar = tarfile.open('test.tar')で開いた元のtarファイルを操作するread()メソッドを含むファイルのようなオブジェクトを返します。

ただし、別のプロセスで開いているファイルを別のプロセスで使用することはできません。そのファイルを再度開く必要があります。私はこれを使用して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() 

し、コードの作業を取得することができたし。

+0

Windowsのサポート: 'if name == '__main__':test_multiproc()' Windowsではフォークがないので、モジュールは最初に '' __parents_main __ ''という名前で新しいプロセスにインポートされ、名前は' '__main __''に戻されます。したがって、 'if'ブロックを使って子プロセスで実行したくないステートメントを保護することができます。 – eryksun

+0

これは動作しますが、すべてのプロセスでtarファイルを再オープンする必要があります。プロセス間でファイル記述子への読み取り専用アクセスを可能にする他の回避策はありますか? –

+0

複数のプロセスがフォークオフする前にデータを先読みするフラグを設定しました。ありがとうございました! –

関連する問題