【问题标题】:web.py + subprocess = hangweb.py + 子进程 = 挂起
【发布时间】:2011-02-17 08:36:09
【问题描述】:

这是我的主文件:

import subprocess, time

pipe = subprocess.PIPE
popen = subprocess.Popen('pythonw -uB test_web_app.py', stdout=pipe)
time.sleep(3)

这里是 test_web_app.py:

import web

class Handler:
  def GET(self):  pass
app = web.application(['/', 'Handler'], globals())
app.run()

当我运行主文件时,程序会执行,但是一个僵尸进程挂起,我必须手动杀死它。为什么是这样?程序结束时如何让 Popen 死掉?只有当我在程序结束前通过管道输出标准输出并休眠一段时间时,Popen 才会挂起。

编辑 -- 这是主文件的最终工作版本:

import subprocess, time, atexit

pipe = subprocess.PIPE
popen = subprocess.Popen('pythonw -uB test_web_app.py', stdout=pipe)

def kill_app():
  popen.kill()
  popen.wait()
atexit.register(kill_app)

time.sleep(3)

【问题讨论】:

    标签: python subprocess popen freeze web.py


    【解决方案1】:

    您还没有waited 处理该过程。完成后,您必须致电popen.wait

    您可以使用popen 对象的poll 方法检查进程是否终止,以查看它是否已完成。

    如果您不需要网络服务器进程的标准输出,您可以简单地忽略标准输出选项。


    您可以使用atexit 模块来实现一个挂钩,该挂钩会在您的主文件退出时被调用。这应该使用Popen 对象的kill 方法,然后对其使用wait 以确保它已终止。

    【讨论】:

    • 子进程永远不会完成......它会永远服务。我希望子进程在父进程结束时终止(当我关闭控制台时)。我需要标准输出。
    【解决方案2】:

    如果您的主脚本在子进程执行时不需要做任何其他事情,我会这样做:

    import subprocess, time
    
    pipe = subprocess.PIPE
    popen = subprocess.Popen('pythonw -uB test_web_app.py', stdout=pipe, stderr=pipe)
    out, err = popen.communicate()
    

    (我认为,如果您专门将 stdout 传送回您的程序,则需要在某个时候读取它以避免创建僵尸进程 - 通信将以相当安全的方式读取它)。

    或者,如果您不关心解析 stdout / stderr,请不要打扰它们:

    popen = subprocess.Popen('pythonw -uB test_web_app.py')
    popen.communicate()
    

    【讨论】:

    • 主脚本确实需要做一些事情。主脚本的真实版本捕获子进程的输出,应用一些花哨的格式,并实时显示输出——非阻塞。
    • 哦,在那种情况下,它有点棘手,我没有做过对不起的事情 - 尽管这个问题可能会为你指明正确的方向:stackoverflow.com/questions/2804543/…
    猜你喜欢
    • 1970-01-01
    • 2017-02-28
    • 2012-09-07
    • 2016-09-23
    • 2015-07-07
    • 1970-01-01
    • 2018-11-11
    • 2013-08-18
    • 1970-01-01
    相关资源
    最近更新 更多