[英]Check if a process is still running
我有以下問題:
我需要我的Python腳本運行bash腳本。 如果bash腳本的運行時間超過10秒,我需要將其殺死。 這是我到目前為止的內容:
cmd = ["bash", "script.sh", self.get_script_path()]
process = subprocess.Popen(cmd)
time.sleep(10) # process running here...
procinfo = psutil.Process(process.pid)
children = procinfo.children(recursive=True)
for child in children:
os.kill(child.pid, signal.SIGKILL)
我擔心的是這種情況:bash腳本在1秒內完成,釋放其PID,系統將PID傳遞給另一個進程。 10秒后,我殺死了我認為它屬於我的腳本的PID,但那不是真的,並且我殺死了其他一些進程。 該腳本需要以root身份運行,因為我需要在其中使用chroot
。
有任何想法嗎?
由於您已經在使用psutil
所以建議您將對subprocess
模塊的調用替換為對psutil.Popen
調用。 這個類有相同的接口subprocess.Popen
但提供的所有功能psutil.Process
。
還要注意的是psutil
為PID庫先發制人檢查已經重用 ,至少在許多方法,包括terminate
和kill
(剛讀出的用於文檔Process
)。
這意味着下面的代碼:
cmd = ["bash", "script.sh", self.get_script_path()]
process = psutil.Popen(cmd)
time.sleep(10) # process running here...
children = process.children(recursive=True)
for child in children:
child.terminate() # try to close the process "gently" first
child.kill()
請注意, children
文檔說:
子項(遞歸= False)
返回該進程的子進程作為
Process
對象的列表, 搶先檢查PID是否已被重用。
總之,這意味着:
children
, psutil
庫會檢查您是否希望子代具有正確的進程,而不是碰巧具有相同pid的子代。 terminate
或kill
庫可以確保您使用相同的PID殺死你的孩子過程,而不是一個隨機過程。 我認為timeout
命令非常適合您。 在文檔頁面上:
概要
超時 [OPTION] NUMBER [SUFFIX]命令[ARG] ...
超時 [OPTION]
描述
啟動COMMAND,如果在NUMBER秒后仍在運行,則將其殺死。 SUFFIX可能是“ s”代表秒(默認值),“ m”代表分鍾,“ h”代表小時或“ d”代表天。
-s ,-- signal = 信號
指定超時時要發送的信號。
SIGNAL可以是“ HUP”之類的名稱或數字。
請參閱“ kill -l”以獲取信號列表
通過timeout
,您不必擔心PID重用,競爭條件等雜亂無章的細節。這些擔憂已很好地封裝在此標准Unix實用程序中。 另一個好處是您的腳本將在子進程提前終止后立即恢復執行,而不用不必要地休眠整整10秒鍾。
bash中的演示:
timeout -s9 10 sleep 11; echo $?;
## Killed
## 137
timeout -s9 10 sleep 3; echo $?;
## 0
python演示:
import subprocess;
subprocess.Popen(['timeout','-s9','10','sleep','11']).wait();
## -9
subprocess.Popen(['timeout','-s9','10','sleep','3']).wait();
## 0
我在ubuntu上使用命令stop process_name停止進程。 可能會有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.