我有一个脚本,它反复运行一个Ant构建文件并将输出转换为可解析格式。当我使用Popen创建子进程时,有一个很小的时间窗口,点击Ctrl + C将会终止脚本,但不会终止运行Ant的子进程,从而将打印输出的僵尸留给只能使用任务终止的控制台经理。一旦Ant开始打印输出,点击Ctrl + C将永远杀死我的脚本以及Ant。有没有办法让它按Ctrl + C总是会杀死运行Ant的子进程而不会留下僵尸?在Python 2.5上可靠地终止子进程
另外值得注意的是:我有一个SIGINT处理程序,它在调用exit(0)之前执行一些清理操作。如果我使用os.kill(p.pid, signal.SIGTERM)
(不是SIGINT)手动终止处理程序中的子进程,那么在通常会发生zombify的情况下,我可以成功地终止子进程。然而,一旦Ant开始产生输出,当你点击Ctrl + C时,你会从子进程中获得一个堆栈跟踪,因为它已经杀死了子进程而无法杀死子进程本身。
编辑:触发错误时
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 and exiting:
try:
p.wait()
except OSError:
exit('The operation was interrupted by the user')
这似乎在绝大多数我的测试运行。我偶尔会得到一个uname: write error: Broken pipe
,但我不知道是什么原因造成的。如果我在子进程开始显示输出之前按Ctrl + C的时间,似乎会发生这种情况。
这就是我在第一次尝试之前,我意识到p.terminate()是在Python 2.6中添加的,而我被困在2.5。不幸的是,我无法升级Python。 –
我终于设法通过尝试围绕对p.wait()的调用并在发生OSError时发生错误而退出。 –