web.py + subprocess = hang

时间:2011-02-17 08:36:09

标签: python subprocess popen hang web.py

这是我的主要文件:

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死掉?如果我在程序结束之前管道stdout并稍微睡了一下,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)

2 个答案:

答案 0 :(得分:2)

您尚未wait进行此处理。完成后,您必须致电popen.wait

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

如果您不需要Web服务器进程的标准输出,则可以忽略stdout选项。


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

答案 1 :(得分:1)

如果您的主脚本在子进程执行时不需要执行任何其他操作,我会执行:

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()