簡體   English   中英

有沒有辦法檢查子進程是否仍在運行?

[英]Is there a way to check if a subprocess is still running?

我在 Python 中使用subprocess.Popen啟動了許多子進程。 我想檢查一個這樣的過程是否已經完成。 我找到了兩種檢查子流程狀態的方法,但似乎都強制流程完成。 一種是使用process.communicate()並打印返回碼,如此處所述: 使用 Python 中的 subprocess.Popen 檢查進程狀態 另一個是簡單地調用process.wait()並檢查它是否返回 0。

有沒有辦法檢查一個進程是否仍在運行而無需等待它完成?

Ouestion : ...一種檢查進程是否仍在運行的方法...

例如,您可以這樣做:

p = subprocess.Popen(...
"""
A None value indicates that the process hasn't terminated yet.
"""
poll = p.poll()
if poll is None:
  # p.subprocess is alive

Python » 3.6.1 文檔 popen-objects

用 Python 測試:3.4.2

myProcessIsRunning = poll() is None 

正如主要答案所建議的那樣,是檢查進程是否正在運行的推薦方法和最簡單的方法。 (它也適用於 jython)

如果您手頭沒有流程實例來檢查它。 然后使用操作系統的TaskList/Ps 進程。

在 Windows 上,我的命令如下所示:

filterByPid = "PID eq %s" % pid
        pidStr = str(pid)
        commandArguments = ['cmd', '/c', "tasklist", "/FI", filterByPid, "|", "findstr",  pidStr ]

這基本上與以下命令行執行相同的操作:

cmd /c "tasklist /FI "PID eq 55588" | findstr 55588"

在 linux 上,我使用以下命令執行完全相同的操作:

pidStr = str(pid)
commandArguments = ['ps', '-p', pidStr ]

ps 命令已經返回錯誤代碼 0 / 1,具體取決於是否找到進程。 在 Windows 上,您需要 find string 命令。

這與以下堆棧溢出線程中討論的方法相同:

驗證進程是否在 JAVA 中使用其 PID 運行

注意:如果您使用這種方法,請記住將您的命令調用包裝在 try/except 中:

try:
    foundRunningProcess = subprocess.check_output(argumentsArray, **kwargs)
    return True
except Exception as err:
    return False

請注意,如果您使用 VS Code 並使用純 Python 和 Jython 進行開發,請小心。 在我的環境中,我錯覺 poll() 方法不起作用,因為我懷疑必須結束的進程確實正在運行。 這個過程啟動了 Wildfly。 在我要求停止 wildfly 之后,shell 仍在等待用戶“按任意鍵繼續......”。

為了完成這個過程,在純 python 中,以下代碼正在運行:

process.stdin.write(os.linesep)

在 jython 上,我必須將此代碼修復為如下所示:

print >>process.stdin, os.linesep

有了這種差異,這個過程確實完成了。 jython.poll() 開始告訴我該過程確實完成了。

正如其他答案所建議的,當子流程尚未返回任何代碼時, None是“返回代碼”的設計占位符。

returncode屬性的文檔支持這一點(強調我的):

子返回碼,由poll()wait()設置(間接由communicate()設置)。 None值表示該進程尚未終止

負值 -N 表示子節點被信號 N 終止(僅限 POSIX)。

出現此None值的一個有趣的地方是在使用timeout參數進行waitcommunicate時。

如果進程在 timeout 秒后沒有終止,則會引發TimeoutExpired異常。

如果您捕獲該異常並檢查 returncode 屬性,它確實是None

import subprocess
with subprocess.Popen(['ping','127.0.0.1']) as p:
    try:
        p.wait(timeout=3)
    except subprocess.TimeoutExpired:
        assert p.returncode is None

如果您查看 subprocess 的源代碼,您會看到引發的異常。 https://github.com/python/cpython/blob/47be7d0108b4021ede111dbd15a095c725be46b7/Lib/subprocess.py#L1930-L1931

如果您在該源中搜索self.returncode is您會發現庫作者依靠None返回代碼設計來推斷應用程序是否正在運行的許多用途。 returncode屬性初始化None並且只在少數地方發生變化,調用_handle_exitstatus的主要流程是傳遞實際的返回碼。

您可以使用 subprocess.check_output 查看您的輸出。

試試這個代碼:

import subprocess
subprocess.check_output(['your command here'], shell=True, stderr=subprocess.STDOUT)

希望這有幫助!

暫無
暫無

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

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