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

3 投票
1 回答
4237 浏览
提问于 2025-04-17 16:01

我在使用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 . . .

看起来在创建新进程的过程中,文件句柄 somehow '丢失' 了。有人能解释一下这是怎么回事吗?

1 个回答

8

我以前也遇到过类似的问题。不是很确定是多进程模块内部的原因,还是说open默认就设置了关闭标志,但我知道在主进程中打开的文件句柄在多进程的子进程中会被关闭

一个明显的解决办法是把文件名作为参数传给子进程的初始化函数,然后在每个子进程中打开这个文件(如果使用的是线程池的话),或者把文件名作为参数传给目标函数,在每次调用时打开和关闭文件。前者需要使用一个全局变量来存储文件句柄(这不是个好主意)——除非有人能告诉我怎么避免这样做 :) — 后者可能会影响性能(但可以直接与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)

撰写回答