参考地址:http://d2100.com/questions/36182
我有一个脚本,反复运行 Ant 生成文件和擦伤成解析格式的输出。当我创建的子进程,使用 Popen 时,有一个小时间窗口位置击球 Ctrl + C 将杀死该脚本,但不是会杀死的子进程运行 Ant,离开打印输出到控制台,才使用任务管理器可杀死的僵尸。一旦蚂蚁已启动打印输出,Ctrl + C 击中总是会杀死我的脚本,以及蚂蚁有没有一个能让它这样打 Ctrl + C 将总是可以杀死的子进程运行 Ant 不会留下一个僵尸吗?
此外说明的: 我有在调用 exit(0) 之前执行几个清理操作的监听的处理程序。如果我手动杀的子进程,在处理程序中使用os.kill(p.pid, signal.SIGTERM)
(不监听),然后成功地杀掉的情况下,它通常将 zombify 的子进程。然而,当你点击 Ctrl + C 蚂蚁开始产生输出后,您可以获得栈跟踪从哪里无法杀死的子进程本身,如已杀死它的子进程的情况。
编辑: <\/strong> 我的代码看起来有点像:
p = Popen('ls')
def handle_sig_int(signum, stack_frame):
# perform cleanup
os.kill(p.pid, signal.SIGTERM)
exit(0)
signal.signal(signal.SIGINT, handle_sig_int)
p.wait()
这会产生以下栈跟踪错误地触发时:
File "****.py", line ***, in run_test
p.wait()
File "/usr/lib/python2.5/subprocess.py", line 1122, in wait
pid, sts = os.waitpid(self.pid, 0)
File "****.py", line ***, in handle_sig_int
os.kill(p.pid, signal.SIGTERM)
我所捕捉的 OSError p.wait 和退出提出定它:
try:
p.wait()
except OSError:
exit('The operation was interrupted by the user')
这似乎在我的测试运行的绝大多数的工作。我偶尔也会看到uname: write error: Broken pipe
,虽然我不知道什么原因。看来如果我时间恰到好处 Ctrl + C,子进程可以开始显示输出之前发生。
回答 #1
调用p.terminate()
SIGTERM 处理程序中:
if p.poll() is None: # Child still around?
p.terminate() # kill it
[编辑] 因为你背负着 Python 2.5,使用os.kill(p.pid, signal.SIGTERM)
而不是p.terminate()
。检查应确保您不会得到一个异常 (或减少你就会得到的次数)。
要使它更好,可以捕获此异常,请检查该消息。如果这意味着"子进程找不到",然后忽略此异常。否则,重新抛出它的raise
(无参数)。