【问题标题】:Forking python, defunct child分叉python,已死的孩子
【发布时间】:2013-08-08 01:16:21
【问题描述】:

我在 Python 子进程方面遇到了一些麻烦,所以我写了一个非常简单的脚本:

import os
import sys
import time

pid = os.fork()
if pid:
    #parent
    time.sleep(30)
else:
    #child
    #os._exit(0)
    sys.exit()

当父进程休眠时我启动

ps fax | grep py[t]hon

我读了这个输出

2577 ?        S      0:00 python /home/pi/python/GPIO/GPIODaemon.py restart
2583 ?        Z      0:00  \_ [python] <defunct>

使用sys.exit()oros._exit(0) 总是有一个僵尸进程,我无法理解为什么。

处理我的更复杂的代码时,我认为有一些资源被子进程保持锁定,但是在这个简化的代码中,子进程根本没有文件/套接字/数据库连接!为什么子进程被僵尸化了?

【问题讨论】:

    标签: python fork zombie-process


    【解决方案1】:

    要在 Unix 中清除子进程,您需要等待子进程,请检查 os.wait()、os.waitpid()、os.wait3() 或 os.wait4() 之一,http://docs.python.org/2/library/os.html#os.wait

    至于为什么会这样,这是 Unix 的设计决定。子进程将其返回值保持在其进程状态,如果它消失,您将没有返回值。 os.wait() 也会给你返回返回值,然后释放子进程,释放所有关联的资源。

    【讨论】:

    • 我 fork 主进程只是为了避免等待。阅读docs.python.org/2/library/os.html#os.wait 似乎父进程会一直休眠到子进程结束。
    • 我自己找到了一个解决方案,但我对此并不满意:我切换了父子代码。所以现在父进程结束(没有僵尸!),孩子成为新的主进程,显然有另一个pid(丑陋)。一切正常,但它不是一个好的编程代码。
    • 崇敬父子不是一个好主意,您可以使用 os.wait4 或 os.waitpid 并使用 os.WNOHANG 选项进行非阻塞等待。阅读与 man 等效的操作系统系统调用,以了解潜在的问题和使用方法。
    【解决方案2】:

    我刚刚遇到了类似的问题:由spawnl 启动的进程可能会结束或可能需要在特定点终止。我没有所有僵尸进程的解决方案是

    def cleanup_subprocesses(self, pid):
      try:
        os.kill(pid, signal.SIGKILL)
      except OSError:
        pass
      os.waitpid(self._pid, 0)
    

    如果进程没有及时结束,它会被杀死,无论如何,waitpid-command都会被执行。

    这显然没有帮助,如果你的程序中没有任何好处,你知道你不再需要这个过程。

    【讨论】:

      猜你喜欢
      • 2012-01-03
      • 1970-01-01
      • 2011-12-13
      • 2015-05-29
      • 1970-01-01
      • 2018-03-26
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多