在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()
5条答案
按热度按时间vjrehmav1#
fileno()
方法返回由运行时库分配的文件号。给定文件号后,您可以调用msvcrt.get_osfhandle()
以获取Win32文件句柄。在调用SetHandleInformation
时使用此句柄。因此,可能会执行以下操作:我不确定
win32api
模块的确切用法,但这应该有助于弥合Python文件对象和Win32句柄之间差距。0tdrvxhp2#
我不知道 multiprocessing 模块,但是使用subprocess模块,您可以指示它不继承任何文件描述符:
如果close_fds为true,则在执行子进程之前,将关闭除0、1和2之外的所有文件描述符。(仅限Unix)。或者,在Windows上,如果close_fds为true,则子进程不会继承任何句柄。请注意,在Windows上,您不能将close_fds设置为true,也不能通过设置stdin、stdout或stderr来重定向标准句柄。
或者,您可以使用os.closerange关闭子进程中的所有文件描述符
关闭从fd_low(包含)到fd_high(不包含)的所有文件描述符,忽略错误。可用性:Unix、Windows操作系统。
qgelzfjb3#
打开文件句柄后,可以使用SetHandleInformation()函数删除
HANDLE_FLAG_INHERIT
标志。rsaldnfx4#
我在使用循环日志和多处理时遇到过这个问题。当父进程尝试循环日志时,它失败并显示
Windows错误:[错误32]进程无法访问文件,因为另一个进程正在使用该文件
根据其他一些答案,以下是python 2.7中防止日志文件处理程序被继承的工作解决方案
请注意,这个问题在python 3.4中有所解决。更多信息请参见https://www.python.org/dev/peps/pep-0446/
scyqe7ek5#
使用
os.set_inheritable
检查此以获取更多详细信息