Python 有没有办法检查子进程是否仍在运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43274476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to check if a subprocess is still running?
提问by ahura
I'm launching a number of subprocesses with subprocess.Popen in Python. I'd like to check whether one such process has completed. I've found two ways of checking the status of a subprocess, but both seem to force the process to complete. One is using process.communicate() and printing the returncode, as explained here. Another is simply calling process.wait() and checking that it returns 0.
我在 Python 中使用 subprocess.Popen 启动了许多子进程。我想检查一个这样的过程是否已经完成。我找到了两种检查子流程状态的方法,但两者似乎都强制流程完成。一种是使用process.communicate()并打印返回代码,如解释在这里。另一个是简单地调用 process.wait() 并检查它是否返回 0。
Is there a way to check if a process is still running without waiting for it to complete if it is?
有没有办法检查进程是否仍在运行而无需等待它完成?
回答by stovfl
Ouestion: ... a way to check if a process is still running ...
Ouestion: ... 一种检查进程是否仍在运行的方法 ...
You can do it for instance:
例如,您可以这样做:
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.6.1 文档 popen-objects
Tested with Python:3.4.2
用 Python 测试:3.4.2
回答by 99Sono
Doing the
做
myProcessIsRunning = poll() is None
As suggested by the main answer, is the recommended way and the simplest way to check if a process running. (and it works in jython as well)
正如主要答案所建议的那样,是检查进程是否正在运行的推荐方法和最简单的方法。(它也适用于 jython)
If you do not have the process instance in hand to check it. Then use the operating system TaskList / Ps processes.
如果您手头没有流程实例来检查它。然后使用操作系统的TaskList/Ps 进程。
On windows, my command will look as follows:
在 Windows 上,我的命令如下所示:
filterByPid = "PID eq %s" % pid
pidStr = str(pid)
commandArguments = ['cmd', '/c', "tasklist", "/FI", filterByPid, "|", "findstr", pidStr ]
This is essentially doing the same thing as the following command line:
这基本上与以下命令行执行相同的操作:
cmd /c "tasklist /FI "PID eq 55588" | findstr 55588"
And on linux, I do exactly the same using the:
在 linux 上,我使用以下命令完全相同:
pidStr = str(pid)
commandArguments = ['ps', '-p', pidStr ]
The ps command will already be returning error code 0 / 1 depending on whether the process is found. While on windows you need the find string command.
ps 命令将已经返回错误代码 0 / 1,具体取决于是否找到进程。在 Windows 上,您需要 find string 命令。
This is the same approach that is discussed on the followig stack overflow thread:
这与在 followig 堆栈溢出线程中讨论的方法相同:
Verify if a process is running using its PID in JAVA
NOTE:
If you use this approach, remeber to wrap your command call in
try:
foundRunningProcess = subprocess.check_output(argumentsArray, **kwargs)
return True
except Exception as err:
return False
注意:如果您使用这种方法,请
记住将您的命令调用包装在try: foundRunningProcess = subprocess.check_output(argumentsArray, **kwargs) return True except Exception as err: return False
Note, be careful if you are developing with VS Code and using pure Python and Jython. On my environment, I was under the illusion that the poll() method did not work because a process that I suspected that must have ended was indeed running. This process had launched Wildfly. And after I had asked for wildfly to stop, the shell was still waiting for user to "Press any key to continue . . .".
请注意,如果您使用 VS Code 进行开发并使用纯 Python 和 Jython,请务必小心。在我的环境中,我错觉 poll() 方法不起作用,因为我怀疑肯定已经结束的进程确实正在运行。这个过程启动了 Wildfly。在我要求 Wildfly 停止之后,shell 仍在等待用户“按任意键继续……”。
In order to finish off this process, in pure python the following code was working:
为了完成这个过程,在纯 python 中,以下代码正在运行:
process.stdin.write(os.linesep)
On jython, I had to fix this code to look as follows:
在 jython 上,我必须修复这段代码,使其看起来如下:
print >>process.stdin, os.linesep
And with this difference the process did indeed finish. And the jython.poll() started telling me that the process is indeed finished.
有了这种差异,这个过程确实完成了。jython.poll() 开始告诉我这个过程确实完成了。
回答by jxramos
As suggested by the other answers None
is the designed placeholder for the "return code" when no code has been returned yet by the subprocess.
正如其他答案所建议的那样,None
当子流程尚未返回任何代码时,为“返回代码”设计的占位符。
The documentation for the returncodeattribute backs this up (emphasis mine):
returncode属性的文档支持这一点(强调我的):
The child return code, set by
poll()
andwait()
(and indirectly bycommunicate()
). ANone
value indicates that the process hasn't terminated yet.A negative value -N indicates that the child was terminated by signal N (POSIX only).
子返回码,由
poll()
和wait()
(间接地由communicate()
)设置。一个None
值表示进程尚未终止。负值 -N 表示子进程被信号 N 终止(仅限 POSIX)。
An interesting place where this None
value occurs is when using the timeout
parameter for waitor communicate.
这个None
值出现的一个有趣的地方是使用timeout
参数等待或通信时。
If the process does not terminate after timeout seconds, a
TimeoutExpired
exception will be raised.
如果进程在 timeout 秒后没有终止,
TimeoutExpired
则会引发异常。
If you catch that exception and check the returncode attribute it will indeed be None
如果您捕获该异常并检查 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
If you look at the source for subprocess you can see the exception being raised. https://github.com/python/cpython/blob/47be7d0108b4021ede111dbd15a095c725be46b7/Lib/subprocess.py#L1930-L1931
如果您查看 subprocess 的源代码,您可以看到引发的异常。 https://github.com/python/cpython/blob/47be7d0108b4021ede111dbd15a095c725be46b7/Lib/subprocess.py#L1930-L1931
If you search that source for self.returncode is
you'll find many uses where the library authors lean on that None
return code design to infer if an app is running or not running. The returncode
attribute is initializedto None
and only ever changes in a few spots, the main flow in invocations to _handle_exitstatus
to pass on the actual return code.
如果您搜索该来源,self.returncode is
您会发现许多用途,其中库作者依靠该None
返回代码设计来推断应用程序是否正在运行或未运行。该returncode
属性被初始化为None
并且只在少数地方发生变化,调用中的主要流程_handle_exitstatus
传递实际返回代码。
回答by nocturnal_beast
You could use subprocess.check_output to have a look at your output.
您可以使用 subprocess.check_output 来查看您的输出。
Try this code:
试试这个代码:
import subprocess
subprocess.check_output(['your command here'], shell=True, stderr=subprocess.STDOUT)
Hope this helped!
希望这有帮助!