【问题标题】:Multiple fork calls cause BlockingIOError多个 fork 调用导致 BlockingIOError
【发布时间】:2017-06-14 10:23:53
【问题描述】:

我正在寻找有关以下 sn-p 错误的解释:

#!/usr/bin/env python3

import os, sys

if __name__ == '__main__':
    while True:
        pid = os.fork()
        if pid == 0:
            sys.exit()
        elif pid > 0:
            pass
            # os.waitpid(pid, 0)
        else:
            sys.exit()

这将产生许多进程(在产生时退出的进程)。

这最终会导致BlockingIOError 显示如下:

Traceback (most recent call last):
  File "./asd.py", line 7, in <module>
    pid = os.fork()
BlockingIOError: [Errno 35] Resource temporarily unavailable

但是当 os.waitpid 调用被取消注释时,一切似乎都很好。

为什么会出现这个错误?这个waitpid 调用可能会改变什么?

【问题讨论】:

    标签: python macos python-3.x fork


    【解决方案1】:

    同样的问题whenever fork dies this way;错误消息就是 EAGAIN 传达给您的方式:

    1. 您的内存不足或
    2. 您已达到进程限制(例如RLIMIT_NPROC

    waitpid 修复它,因为它会收获僵尸子进程;在您这样做之前,这些进程将计入上限(它必须保留它们,以便父级可以查看终止信息)。

    您可以查看its man page 上记录的各种fork 错误代码。

    【讨论】:

    • 感谢您提供这个非常有用的答案。我有一个程序对可能超时的生成进程进行大量fork 调用。在这种情况下,进程只是被父进程用 os.kill 杀死(根据你的回答,这还不够)。如果我能很好地理解您的回答,请致电 waitpid() 处理超时的进程。但是有没有一个函数可以只“收获”这些过程而不检索信息? (因为我不需要它,因为我知道在这种情况下进程是如何终止的)。
    • @vmonteco:您可以通过setting the SIGCHLD handler to SIG_IGN explicitly 让父进程全局退出处理子进程; Python 提供对signal 模块中信号处理程序设置的访问。这意味着您无法获得已经退出的孩子的退出状态。还有一个double-fork + setsid 的方案来创建具有类似效果的守护进程(可以立即收获中间子进程,而孙子进程分离)。
    • 我检查了你的评论,最后 waitpid() 似乎是最好的解决方案(我仍然需要获取其他进程的退出状态,并且设置一个孙子进程似乎无用复杂)。是的,你的链接让我学到了东西,再次感谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 2021-09-13
    • 2013-10-20
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多