我有一個腳本,它反覆運行一個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時發生錯誤而退出。 –