Python多进程,ValueError:在关闭的文件上进行了I/O操作

3
我在使用Python的multiprocessing包时遇到了问题。以下是一个简单的示例代码,说明了我的问题。
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
如果你点击左上角的控制台图标,你会找到菜单选项来选择和复制文本。使用该功能将回溯信息作为文本复制到你的帖子中。 - Martijn Pieters
1
你可能想要将输出存储在队列中,当所有进程完成后,从队列中取出输出并通过主进程写出。 - pyInTheSky
1个回答

8

我曾经遇到过类似的问题。不确定是在多进程模块内部完成还是open默认设置了close-on-exec标志,但我确定主进程打开的文件句柄会在多进程子进程中被关闭。

显而易见的解决方法是将文件名作为参数传递给子进程的初始化函数,并在每个子进程中打开一次(如果使用池),或将其作为参数传递给目标函数并在每次调用时打开/关闭。前者需要使用全局变量来存储文件句柄(不是好事)-除非有人可以向我展示如何避免:) - 后者可能会带来性能损失(但可以直接使用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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接