我在Python中使用subprocess.Popen启动了许多子进程。 我想检查一个这样的过程是否已经完成。我发现了两种检查子进程状态的方法,但两者似乎都迫使进程完成。 一个是使用process.communicate()并打印返回码,如here所述。 另一个是简单地调用process.wait()并检查它是否返回0。
有没有办法检查进程是否仍在运行而不等待它完成?
答案 0 :(得分:33)
Ouestion :...检查进程是否仍在运行的方法......
你可以这样做:
p = subprocess.Popen(...
"""
A None value indicates that the process hasn't terminated yet.
"""
poll = p.poll()
if poll == None:
# p.subprocess is alive
Python » 3.6.1 Documentation popen-objects
使用Python测试:3.4.2
答案 1 :(得分:3)
执行
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命令。
这与followig stack overflow thread讨论的方法相同:
Verify if a process is running using its PID in JAVA
注意: 如果您使用此方法,请记住将命令调用包装在中 尝试: foundRunningProcess = subprocess.check_output(argumentsArray,** kwargs) 返回True 除了例外错误: 返回False
注意,如果您使用VS Code进行开发并使用纯Python和Jython,请务必小心。 在我的环境中,我认为poll()方法不起作用,因为我怀疑必须已经结束的进程确实正在运行。 这个过程推出了Wildfly。在我要求野蝇停止后,外壳仍在等待用户“按任意键继续......”。
为了完成这个过程,在纯python中,以下代码正在运行:
process.stdin.write(os.linesep)
在jython上,我必须修改此代码,如下所示:
print >>process.stdin, os.linesep
由于这种差异,这个过程确实完成了。 并且jython.poll()开始告诉我该过程确实已经完成。
答案 2 :(得分:0)
您可以使用subprocess.check_output来查看输出。
试试这段代码:
import subprocess
subprocess.check_output(['your command here'], shell=True, stderr=subprocess.STDOUT)
希望这有帮助!
答案 3 :(得分:0)
如其他答案所建议,None
是子进程尚未返回任何代码时为“返回代码”设计的占位符。
returncode属性的文档对此进行了支持(强调我的意思):
子返回码,由
poll()
和wait()
设置(间接由communicate()
设置)。None
值表示该过程尚未终止。负值-N表示该子对象已被信号N终止(仅适用于POSIX)。
出现None
值的一个有趣地方是将wait或communicate的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
如果查看子流程的源代码,则可以看到正在引发的异常。 https://github.com/python/cpython/blob/47be7d0108b4021ede111dbd15a095c725be46b7/Lib/subprocess.py#L1930-L1931
如果您在源中搜索self.returncode is
,则会发现许多用途,库作者依靠该None
返回代码设计来推断应用程序是否正在运行。 returncode
属性是initialized到None
,并且仅在几个位置发生变化,这是对_handle_exitstatus
的调用的主要流程,以传递实际的返回代码。