Kill python subprocess when timeout

在 subprocess timeout 時,終結子進程

Lau Dai He
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 GroupSession 等以及調用start_new_session選項。

對於此程式有興趣的讀者,可以使用下面兩組程式碼進行測試,執行 python檔案時,可以測試保留註解以及拿掉註解後,會有什麼差異。

單純執行 bash script 結果
#!/usr/local/bin bashtestfilename=/tmp/testfileecho "check $testfilename exist or not?"
[ -f $testfilename ] && echo "$testfilename exists." || echo "$testfilename not exists"
echo
sleep 10echo "new file $testfilename"
echo
touch $testfilename
echo "check $testfilename exist or not?"
[ -f $testfilename ] && echo "$testfilename exists." || echo "$testfilename not exists"
執行 python 結果(保留註解)
執行 python 結果(移除註解)
#!/usr/bin/env python
# encoding: utf8
# Author : laudai
import subprocess
import os
import signal
cmd = ["/usr/bin/env","bash","/home/laudai/touchfile.sh"]
timeout_sec = 5
try:
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()

--

--

Lau Dai He
Lau Dai He

Written by Lau Dai He

Less is more. 2021/08/01起,主要會紀錄各種技術的精華重點文章,方向可能是Pyhton, Linux, WIndows等都有可能。文章內容精簡為主,搭配少部份的個人情感抒發等。(inspired by 路人甲的世界​-知乎作者)

No responses yet