防止多处理库中的文件句柄继承
在 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()
Using multiprocessing on windows it appears that any open file handles are inherited by spawned processes. This has the unpleasant side effect of locking them.
I'm interested in either:
1) Preventing the inheritance
2) A way to release the file from the spawned process
Consider the following code which works fine on OSX, but crashes on windows at 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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用 os.set_inheritable 检查这个 了解更多详情
use
os.set_inheritable
check this for more details打开文件句柄后,可以使用 SetHandleInformation() 函数删除
HANDLE_FLAG_INHERIT
标志。After you open a file handle, you can use the SetHandleInformation() function to remove the
HANDLE_FLAG_INHERIT
flag.我在使用旋转日志和多重处理时遇到了这个问题。 当父进程尝试轮换日志时,它会失败并显示
WindowsError: [Error 32] 该进程无法访问该文件,因为根据其他一些答案,
,以下是 python 2.7 中的一个工作解决方案,用于防止继承日志文件处理程序请注意此问题是python 3.4 中的一些地址。 欲了解更多信息,请参阅
https://www.python.org/dev/peps/pep-0446/
I have encountered this issue when using a rotating log and multiprocessing. When the parent process tries to rotate the log, it fails with a
based on some of the other answers, the following is a working solution in python 2.7 to prevent log file handlers from been inherited
Please note this issue was somewhat address in python 3.4. for more info see
https://www.python.org/dev/peps/pep-0446/
我不知道多处理模块,但使用subprocess 模块,您可以指示它不继承任何文件描述符:
或者,您可以使用 os.closerange
I don't know about the multiprocessing module, but with the subprocess module you can instruct it to not inherit any file descriptors:
Alternatively you could close all file descriptors in your child process with os.closerange
fileno()
方法返回运行时库分配的文件号。 给定文件号,您就可以调用msvcrt.get_osfhandle()
来获取 Win32 文件句柄。 在对SetHandleInformation
的调用中使用此句柄。 因此,类似以下内容可能会起作用:我不确定
win32api
模块的确切用法,但这应该有助于弥合 Python 文件对象和 Win32 句柄之间的差距。The
fileno()
method returns the file number as assigned by the runtime library. Given the file number, you can then callmsvcrt.get_osfhandle()
to get the Win32 file handle. Use this handle in the call toSetHandleInformation
. So something like the following may work:I'm not certain of the exact usage of the
win32api
module, but this should help bridge the gap between a Python file object and a Win32 handle.