2017-06-14 140 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

相關問題