Kill python subprocess when timeout
在 subprocess timeout 時,終結子進程
4 min readJun 12, 2022
Author:Lau Dai
Date:2022/06/12
在 subprocess 模組中,有個 timeout 的選項,之前在使用的時候會很自然以為調用此模組後,若觸發 timeout 會將子進程一併中斷。 但在實際運作過後才發現並非如此。
timeout 觸發後會 raise 事件,但原本的子進程會仍在背景執行。
因此,若要解決此問題,最好的辦法就是在 timeout 後,同時將子進程 kill 即可。
對此已經有人寫了一篇文章,裡面有十分詳細的說明發生的原因,以及如何處理。文章連結:Kill a Python subprocess and its children when a timeout is reached
在此文章中有說明 Process Group、Session 等以及調用start_new_session
選項。
對於此程式有興趣的讀者,可以使用下面兩組程式碼進行測試,執行 python檔案時,可以測試保留註解以及拿掉註解後,會有什麼差異。
#!/usr/local/bin bashtestfilename=/tmp/testfileecho "check $testfilename exist or not?"
[ -f $testfilename ] && echo "$testfilename exists." || echo "$testfilename not exists"
echosleep 10echo "new file $testfilename"
echo
touch $testfilenameecho "check $testfilename exist or not?"
[ -f $testfilename ] && echo "$testfilename exists." || echo "$testfilename not exists"
#!/usr/bin/env python
# encoding: utf8
# Author : laudaiimport subprocess
import os
import signalcmd = ["/usr/bin/env","bash","/home/laudai/touchfile.sh"]
timeout_sec = 5try:
cp = subprocess.Popen(cmd)
cp.wait(timeout_sec)
except subprocess.TimeoutExpired:
print(f"run subprocess timeout {timeout_sec} seconds")
#print("will kill subprocess via send signal TERM to subprocess")
#os.killpg(os.getpgid(cp.pid), signal.SIGTERM)
— 2022/09/20 更新 —
在官方文件中,可以使用下列兩種方式送出 Signal,結束 timeout 的子程序
proc.terminate()
proc.kill()