簡體   English   中英

在拋出 subprocess.TimeoutExpired 后殺死 Python 子進程的子進程

[英]Kill children of Python subprocess after subprocess.TimeoutExpired is thrown

我在 Python 中調用了一個 shell 腳本,它會產生多個子進程。 如果兩分鍾后沒有完成,我想終止該進程及其所有子進程。

有什么辦法可以用 subprocess.run 做到這一點,還是我必須回去使用 Popen? 由於 run 被阻塞,我無法將 pid 保存在某處以在額外的命令中殺死孩子。 一個簡短的代碼示例:

try:
    subprocess.run(["my_shell_script"], stderr=subprocess.STDOUT, timeout=120)
except subprocess.TimeoutExpired:                                                                      
    print("Timeout during execution")

此問題已作為錯誤報告給 Python 開發人員。 當 stderr 或 stdout 被重定向時,它似乎特別發生。 這是@Tanu 代碼的更正確版本。

import subprocess as sp

try:
    proc = sp.Popen(['ls', '-l'], stdout=sp.PIPE, stderr=sp.PIPE)
    outs, errs = proc.communicate(timeout=120)
except sp.TimeoutExpired:
    proc.terminate()

Popen 不接受timeout作為參數。 必須通過它才能進行communicate 在 Posix 操作系統上, terminatekill更溫和,因為它降低了創建僵屍進程的風險。

引用文檔:

subprocess.run - 默認情況下不會捕獲 stdout 或 stderr。 為此,請為 stdout 和/或 stderr 參數傳遞 PIPE。

如果您不想,不必使用 Popen()。 模塊中的其他函數,例如 .call()、.Popen()。

有三個“文件”流:用於輸入的 stdin,以及用於輸出的 stdout 和 stderr。 應用程序決定在哪里寫什么; 通常錯誤和診斷信息到 stderr,其余到 stdout。 要捕獲這些輸出中的任何一個的輸出,請指定 subprocess.PIPE 參數,以便將“流”重定向到您的程序中。

超時后終止子進程:

import os
import signal
import subprocess

try:
    proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE, timeout=120)
except subprocess.TimeoutExpired:
    os.kill(proc.pid, signal.SIGTERM)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM