Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 防止多处理库中的文件句柄继承_Python_Windows_Multiprocessing_Handle - Fatal编程技术网

Python 防止多处理库中的文件句柄继承

Python 防止多处理库中的文件句柄继承,python,windows,multiprocessing,handle,Python,Windows,Multiprocessing,Handle,在windows上使用多处理时,任何打开的文件句柄似乎都会被派生的进程继承。这会产生令人不快的副作用,即锁定它们 我对任何一种都感兴趣: 1) 防止继承 2) 从衍生进程中释放文件的方法 考虑以下代码,它在OSX上运行良好,但在windows os.rename上崩溃 from multiprocessing import Process import os kFileA = "a.txt" kFileB = "b.txt" def emptyProcess(): while 1:

在windows上使用多处理时,任何打开的文件句柄似乎都会被派生的进程继承。这会产生令人不快的副作用,即锁定它们

我对任何一种都感兴趣:
1) 防止继承
2) 从衍生进程中释放文件的方法

考虑以下代码,它在OSX上运行良好,但在windows 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()

打开文件句柄后,可以使用SetHandleInformation()函数删除
handle\u标志\u INHERIT
标志。

我不知道多处理模块,但使用该模块可以指示它不继承任何文件描述符:

如果close_fds为true,则在执行子进程之前,将关闭除0、1和2之外的所有文件描述符。(仅限Unix)。或者,在Windows上,如果close_fds为true,则子进程将不会继承任何句柄。请注意,在Windows上,不能将close_fds设置为true,也不能通过设置stdin、stdout或stderr重定向标准句柄

或者,您可以使用关闭子进程中的所有文件描述符

关闭从fd_low(包含)到fd_high(独占)的所有文件描述符,忽略错误。可用性:Unix、Windows

fileno()
方法返回运行库分配的文件号。给定文件号,然后可以调用
msvcrt.get\u osfhandle()
获取Win32文件句柄。在调用
SetHandleInformation
时使用此句柄。因此,类似以下的方法可能会起作用:

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

我不确定
win32api
模块的确切用法,但这应该有助于缩小Python文件对象和Win32句柄之间的差距。

我在使用旋转日志和多处理时遇到了这个问题。当父进程尝试旋转日志时,它会失败,出现错误

WindowsError:[错误32]该进程无法访问该文件,因为其他进程正在使用该文件

基于其他一些答案,以下是Python2.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
请注意,这个问题在Python3.4中有所解决。有关更多信息,请参阅

如何从使用open()而不是os.open()创建的文件中获取文件句柄?我知道subprocess标志,但我特别询问多处理模块。此外,如果我们有另一个管道或文件,我们确实希望继承close_fds标志,这有点过于苛刻。@Villalian如果您想保留继承的文件描述符,您需要将此信息传递给子流程,以便它知道不关闭哪个文件描述符。没有别的办法了。