【问题标题】:exit and clean up python fork退出并清理 python fork
【发布时间】:2016-02-18 10:45:34
【问题描述】:

我正在尝试在 python 中使用 fork 编写套接字服务器。当客户端连接时,会以某种方式创建一个新的分叉,这个分叉进程将处理包括发送/接收在内的连接。
我在 Linux centOS 上运行了这个脚本,并使用 htop/top 监视资源以查看显示了多少分叉(任务)。这 问题是当我使用os._exit(0) 杀死一些叉子时,htop 不会改变(自然必须通过杀死叉子来减少它),当我关闭 python 脚本时,一切都会恢复正常(Ram 使用和任务)。 所以当我使用os._exit(0) 杀死一些fork 时,我必须这样做,另一方面它会影响htop 释放所有资源并且不要等到它自己的父级被杀死?

这是创建分叉的代码:

def test(sock):
     //handle socket then return
for i in range (1000):
     sock,addr=socket.accept()
     pid=os.fork()
     if pid==0:
          test(sock)
          os._exit(0)
     elif pid !=-1:
          os.waitpid(-1, os.WNOHANG)

【问题讨论】:

    标签: python linux fork htop


    【解决方案1】:

    父进程需要等待子进程才能释放子进程的资源。在那之前,该进程仍然处于“僵尸”状态,它仍然会出现在pstop等中。

    您可以拨打os.wait()os.waitpid()os.wait3()os.wait4() 之一。

    os.wait3() 带有os.WNOHANG 选项可能对您最有用,因为它会等待任何子进程并且父进程不会阻塞,直到子进程终止(或者它的状态更改 - wait 将返回子进程也已停止或重新启动)。

    有关底层系统调用的更多详细信息,请参见 Linux 手册页:man 2 wait

    【讨论】:

    • 我在 parent 中使用了os.waitpid(childPID,0)。但是在子进程完成并退出之前,父级不再接受任何连接。但是当我在 fork 进程中使用os._exit(0) 时,它会在 ps 或 top 中消失。另一方面释放所有资源。但现在如果我创建 1000 个分叉,甚至将它们全部销毁(os._exit(0)),似乎top or ps 仍然显示任务 = 1000。似乎叉子不干净或类似的东西。但是当我终止 python 进程并停止每一个它时,一切都会好起来的
    • @MehrdadDadvand:父级将不再接受任何连接,因为它被阻止等待子级终止。您可以运行os.waitpid(childPID,os.WNOHANG) 并且父级不会阻塞,并且将返回(0, return_code) 指示子级终止,如果没有,则返回(childPID,return_code)。我在回答中提到了os.wait3(os.WNOHANG),它与`os.waitpid(-1, os.WNOHANG) 几乎相同,但它返回有关子进程的额外资源信息,这可能对登录父进程有用。跨度>
    • 我觉得这里还是有小问题。我在顶部使用了os.waitpid(-1,os.WNOHANG)tasks,不会随着分叉终止而更新。但它不会像以前的代码那样增加。
    • 当我运行我的 scripy 时,我可以在 top 中看到很多任务僵尸字段。我认为任务仍处于僵尸状态
    • 没有看到有问题的代码就很难发表评论。您是否多次致电os.waitpid()?它在返回什么? - 它实际上是返回一个终止的孩子的 PID,还是 0(在这种情况下它没有加入任何孩子)。?也许您可以在您的问题中添加一个代码的最小工作示例。
    猜你喜欢
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2012-05-12
    • 2015-02-05
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多