2017-06-14 137 views
0

我在寻找有关错误我用下面的代码片段获得解释:多叉调用会导致BlockingIOError

#!/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可以调用它的变化?

回答

1

这是同样的问题whenever fork dies this way;该错误信息是EAGAIN只是如何传达给你:

  1. 你的内存不足或
  2. 你已经打了进程限制(例如RLIMIT_NPROC

waitpid修复它,因为它收获僵尸子进程;直到你这样做,这些过程才算上限(它必须保留它们,以便父母可以查看终止信息)。

您可以在its man page上看到各种fork错误代码。

+0

谢谢你这个非常有帮助的答案。 我有一个程序,使得大量'fork'调用产生可能超时的进程。 在这种情况下,进程被os.kill(根据你的回答是不够的)被父进程杀死。如果我很好地理解了你的答案,那么也可以调用'waitpid()'来处理超时的进程。 但是,有没有一个函数可以用来“收获”这些过程而不需要检索信息? (因为我不需要它,因为我知道在这种情况下流程是如何终止的)。 – vmonteco

+1

@vmonteco:你可以通过将[SIGCHLD'处理程序明确设置为'SIG_IGN'](https://en.wikipedia.org/wiki/Zombie_process#Overview),让父母全局选择退出处理子进程。 Python可以访问'signal'模块中的信号处理器设置。这意味着您无法获得已退出的孩子的退出状态。还有一个double-'fork' +'setsid'解决方案来创建具有相似效果的守护进程(您可以立即收获中间子进程,并且将孙子分离)。 – ShadowRanger

+0

我检查了你的评论,并最终waitpid()似乎是最好的解决方案(我仍然需要获得其他进程的退出状态,并且设置孙子进程似乎无用地复杂)。你的链接学到了我的东西,再次感谢你! – vmonteco

相关问题