Python 文件在进程中使用时自动关闭

Python 文件在进程中使用时自动关闭,python,file,python-2.7,multiprocessing,Python,File,Python 2.7,Multiprocessing,以下代码工作: import multiprocessing import threading import time file_path = 'C:/TEST/0000.txt' class H(object): def __init__(self, path): self.hash_file = open(file_path, 'rb') def read_line(self): print self.hash_file.readline(

以下代码工作:

import multiprocessing
import threading
import time

file_path = 'C:/TEST/0000.txt'

class H(object):
    def __init__(self, path):
        self.hash_file = open(file_path, 'rb')
    def read_line(self):
        print self.hash_file.readline()

h = H(file_path)
h.read_line()
但当我在过程中使用时:

import multiprocessing
import threading
import time

file_path = 'C:/TEST/0000.txt'

class Worker(multiprocessing.Process):
    def __init__(self, path):
        super(Worker, self).__init__()
        self.hash_file = open(path, 'rb')
    def run(self):
        while True:
            for i in range(1000):
                print self.hash_file.readline()
                time.sleep(1.5)


if __name__ == '__main__':
    w = Worker(file_path)
    w.start()
    w.join()
引发异常:

Process Worker-1:
Traceback (most recent call last):
  File "E:\Python27\lib\multiprocessing\process.py", line 258, in _bootstrap
    self.run()
  File "C:\ts_file_open.py", line 31, in run
    print self.hash_file.readline()
ValueError: I/O operation on closed file

因为
open
花费很多,而且我只需要读取文件,我想打开一次就足够了。但是为什么在进程运行时关闭这个文件对象呢?我还想将此文件对象传递给子进程和子进程的子线程。

这会失败,因为您正在父进程中打开文件,但试图在子进程中使用它。Windows上的子进程不会继承父进程中的文件描述符(因为它没有使用
os.fork
创建新进程),因此子进程中的读取操作失败。请注意,由于
os.fork
的性质,该代码实际上可以在Linux上运行,因为文件描述符由子级继承


另外,我认为
open
操作本身并不特别昂贵。实际上读取文件可能会很昂贵,但打开操作本身应该很快。

这会失败,因为您在父进程中打开文件,但试图在子进程中使用它。Windows上的子进程不会继承父进程中的文件描述符(因为它没有使用
os.fork
创建新进程),因此子进程中的读取操作失败。请注意,由于
os.fork
的性质,该代码实际上可以在Linux上运行,因为文件描述符由子级继承


另外,我认为
open
操作本身并不特别昂贵。实际上,读取文件可能会很昂贵,但打开操作本身应该很快。

尝试用
run()
方法打开文件。@monkut我知道这会起作用,但为什么呢?你在一个过程中创建了Worker实例,另一个调用了run。@monkut这种行为有点奇怪。@monkut我在process
start
方法中看到了
Popen
。这似乎是重点。试着用
run()
方法打开文件。@monkut我知道这会起作用,但为什么?在一个进程中创建Worker实例,另一个调用了run。@monkut这种行为有点奇怪。@monkut我在process
start
方法中看到了
Popen
。这似乎是重点。在windows和unix下的Python 3.4+中,默认情况下,Per all描述符是不可继承的。这一鼓舞人心的讲话增加了一堆的热情。添加
os.set可继承(self.hash\u file.fileno(),False)
in
(但在unix中不需要,因为它是多进程调用而不是子进程调用)。默认情况下,windows和unix下的Python 3.4+中的每个描述符都不可继承。这一鼓舞人心的讲话增加了一堆的热情。在
\uuuu init\uuuu
方法中添加
os.set\u可继承(self.hash\u file.fileno(),False)
应该可以使它在windows 3.4+中工作(但在unix中不是必需的,因为它是一个多进程调用而不是子进程调用)。