3

Pythonマルチプロセッシングパッケージに問題があります。以下は私の問題を説明する簡単なサンプルコードです。

import multiprocessing as mp
import time

def test_file(f):
  f.write("Testing...\n")
  print f.name
  return None

if __name__ == "__main__":
  f = open("test.txt", 'w')
  proc = mp.Process(target=test_file, args=[f])
  proc.start()
  proc.join()

これを実行すると、次のエラーが発生します。

Process Process-1:
Traceback (most recent call last):
  File "C:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
    self.run()
  File "C:\Python27\lib\multiprocessing\process.py", line 114, in run
    self.target(*self._args, **self._kwargs)
  File "C:\Users\Ray\Google Drive\Programming\Python\tests\follow_test.py", line 24, in test_file
    f.write("Testing...\n")
ValueError: I/O operation on closed file
Press any key to continue . . .

新しいプロセスの作成中に、どういうわけかファイルハンドルが「失われた」ようです。誰かが何が起こっているのか説明してもらえますか?

4

1 に答える 1

8

私は過去に同様の問題を抱えていました。マルチプロセッシングモジュール内で実行されるのかopen、デフォルトでclose-on-execフラグが設定されるのかはわかりませんが、メインプロセスで開かれたファイルハンドルがマルチプロセッシングの子で閉じられることは確かです。

明らかな回避策は、ファイル名をパラメーターとして子プロセスのinit関数に渡して、各子内で1回開くか(プールを使用している場合)、またはパラメーターとしてターゲット関数に渡して、それぞれで開閉することです。呼び出し。前者はファイルハンドルを格納するためにグローバルを使用する必要があります(これを回避する方法を誰かが教えてくれない限り:)-後者はパフォーマンスに影響を与える可能性があります(ただし、multiprocessing.Processで直接使用できます) )。

前者の例:

filehandle = None

def child_init(filename):
    global filehandle
    filehandle = open(filename,...)
    ../..

def child_target(args):
    ../..

if __name__ == '__main__':
    # some code which defines filename
    proc = multiprocessing.Pool(processes=1,initializer=child_init,initargs=[filename])
    proc.apply(child_target,args)
于 2013-02-15T17:11:13.157 に答える