2009-06-04 73 views
11

在Windows上使用多處理時,似乎任何打開的文件句柄都會被生成的進程繼承。這有鎖定他們的不愉快的副作用。防止多處理庫中的文件句柄繼承

我感興趣的兩種:
1)防止窗戶上的繼承
2)從衍生進程

考慮下面的代碼在OSX工作正常釋放文件的一種方式,但崩潰在os.rename

from multiprocessing import Process 
import os 

kFileA = "a.txt" 
kFileB = "b.txt" 

def emptyProcess(): 
    while 1: 
     pass 

def main(): 
    # Open a file and write a message 
    testFile = open(kFileA, 'a') 
    testFile.write("Message One\n") 

    # Spawn a process 
    p = Process(target=emptyProcess) 
    p.start() 

    # Close the file 
    testFile.close() 

    # This will crash 
    # WindowsError: [Error 32] The process cannot access the file 
    #    because it is being used by another process 
    os.rename(kFileA, kFileB) 

    testFile = open(kFileA, 'a') 
    testFile.write("Message Two\n") 
    testFile.close() 

    p.terminate() 


if __name__ == "__main__": 
    main() 

回答

0

在打開的文件句柄,你可以使用SetHandleInformation()函數刪除HANDLE_FLAG_INHERIT標誌。

+0

如何從使用open()創建的文件獲取文件句柄,而不是os.open()? – 14256424 2009-06-04 17:54:45

1

我不知道該多處理模塊,但與subprocess模塊,您可以指示它沒有繼承任何文件描述符:

If close_fds is true, all file descriptors except 0, 1 and 2 will be closed before the child process is executed. (Unix only). Or, on Windows, if close_fds is true then no handles will be inherited by the child process. Note that on Windows, you cannot set close_fds to true and also redirect the standard handles by setting stdin, stdout or stderr.

另外,您可以關閉所有的文件描述符在你的子進程與os.closerange

Close all file descriptors from fd_low (inclusive) to fd_high (exclusive), ignoring errors. Availability: Unix, Windows.

+2

我知道子進程標誌,但我特別提到了多處理模塊。另外,如果我們有另一個管道或文件,我們確實想要繼承close_fds標誌,這有點沉重。 – 14256424 2009-06-04 17:56:57

4

fileno()方法返回作爲由運行時庫分配的文件編號。給定文件編號,然後可以調用msvcrt.get_osfhandle()來獲取Win32文件句柄。在致電SetHandleInformation時使用此句柄。因此,像下面這樣可以工作:

win32api.SetHandleInformation(
    msvcrt.get_osfhandle(testFile.fileno()), 
    win32api.HANDLE_FLAG_INHERIT, 
    0) 

我不能肯定的win32api模塊的確切用法,但這應該幫助彌補Python文件對象和一個Win32手柄之間的差距。

0

我在使用旋轉日誌和多處理時遇到此問題。當父進程試圖旋轉日誌,它不能用

WindowsError: [Error 32] The process cannot access the file because it is being used by another process

基於一些其他的答案

,以下是在Python 2.7可行的解決方案,以防止日誌文件處理程序從被繼承

fd = logging.getLogger().handlers[0].stream.fileno() # The log handler file descriptor 
fh = msvcrt.get_osfhandle(fd) # The actual windows handler 
win32api.SetHandleInformation(fh, win32con.HANDLE_FLAG_INHERIT, 0) # Disable inheritance 

請注意這個問題有點在python 3.4中的地址。欲瞭解更多信息,請參閱 https://www.python.org/dev/peps/pep-0446/