Python 防止多处理库中的文件句柄继承
在windows上使用多处理时,任何打开的文件句柄似乎都会被派生的进程继承。这会产生令人不快的副作用,即锁定它们 我对任何一种都感兴趣: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:
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如果您想保留继承的文件描述符,您需要将此信息传递给子流程,以便它知道不关闭哪个文件描述符。没有别的办法了。