2

这是我的主文件:

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

2 回答 2

2

您还没有等待该过程。完成后,您必须调用popen.wait.

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

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


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

于 2011-02-17T09:10:18.543 回答
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 / stderr,请不要打扰它们:

popen = subprocess.Popen('pythonw -uB test_web_app.py')
popen.communicate()
于 2011-02-17T09:49:14.470 回答