简体   繁体   English

有没有办法检查子进程是否仍在运行?

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

I'm launching a number of subprocesses with subprocess.Popen in Python.我在 Python 中使用subprocess.Popen启动了许多子进程。 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: checking status of process with subprocess.Popen in Python .一种是使用process.communicate()并打印返回码,如此处所述: 使用 Python 中的 subprocess.Popen 检查进程状态 Another is simply calling process.wait() and checking that it returns 0.另一个是简单地调用process.wait()并检查它是否返回 0。

Is there a way to check if a process is still running without waiting for it to complete if it is?有没有办法检查一个进程是否仍在运行而无需等待它完成?

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 is 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

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. ps 命令已经返回错误代码 0 / 1,具体取决于是否找到进程。 While on windows you need the find string command.在 Windows 上,您需要 find string 命令。

This is the same approach that is discussed on the following stack overflow thread:这与以下堆栈溢出线程中讨论的方法相同:

Verify if a process is running using its PID in JAVA 验证进程是否在 JAVA 中使用其 PID 运行

NOTE: If you use this approach, remember to wrap your command call in a try/except:注意:如果您使用这种方法,请记住将您的命令调用包装在 try/except 中:

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.请注意,如果您使用 VS Code 并使用纯 Python 和 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.在我的环境中,我错觉 poll() 方法不起作用,因为我怀疑必须结束的进程确实正在运行。 This process had launched Wildfly.这个过程启动了 Wildfly。 And after I had asked for wildfly to stop, the shell was still waiting for user to "Press any key to continue . . .".在我要求停止 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() 开始告诉我该过程确实完成了。

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 returncode attribute backs this up (emphasis mine): returncode属性的文档支持这一点(强调我的):

The child return code, set by poll() and wait() (and indirectly by communicate() ).子返回码,由poll()wait()设置(间接由communicate()设置)。 A None value indicates that the process hasn't terminated yet . None值表示该进程尚未终止

A negative value -N indicates that the child was terminated by signal N (POSIX only).负值 -N 表示子节点被信号 N 终止(仅限 POSIX)。

An interesting place where this None value occurs is when using the timeout parameter for wait or communicate .出现此None值的一个有趣的地方是在使用timeout参数进行waitcommunicate时。

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.如果您查看 subprocess 的源代码,您会看到引发的异常。 https://github.com/python/cpython/blob/47be7d0108b4021ede111dbd15a095c725be46b7/Lib/subprocess.py#L1930-L1931 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.如果您在该源中搜索self.returncode is您会发现库作者依靠None返回代码设计来推断应用程序是否正在运行的许多用途。 The returncode attribute is initialized to None and only ever changes in a few spots, the main flow in invocations to _handle_exitstatus to pass on the actual return code. returncode属性初始化None并且只在少数地方发生变化,调用_handle_exitstatus的主要流程是传递实际的返回码。

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!希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM