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

ahu*_*ura 32 python subprocess

我在Python中使用subprocess.Popen启动了许多子进程.我想检查一个这样的过程是否已经完成.我发现了两种检查子进程状态的方法,但两者似乎都迫使进程完成.一种是使用process.communicate()并打印返回代码,如解释在这里.另一个是简单地调用process.wait()并检查它是否返回0.

有没有办法检查进程是否仍在运行而不等待它完成?

sto*_*vfl 43

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
Run Code Online (Sandbox Code Playgroud)

Python»3.6.1文档popen-objects

用Python测试:3.4.2

  • 语义,但我相信`如果poll是None`是编写它的首选方式. (11认同)
  • 我可以做p.poll().即使在完成该过程后,这也会返回None.我知道这是因为我调用的脚本会生成一个出现的输出文件,但仍会返回None.另外,我可以打印p.wait(),它给出0,但之后打印p.poll()仍然给出None. (4认同)
  • 我一开始对这个解决方案有疑问,因为我在 p.terminate 之后立即使用 p.poll 并且仍然没有得到任何结果。在两者之间添加一个小的延迟可以解决这个问题。如果其他人遇到此问题,希望这会有所帮助。 (3认同)
  • 唉,对不起,我犯了一个错误,并在创建它之后在新流程上使用民意调查,而不是旧流程.p.poll()确实是这样做的方法(在运行时为None,在成功完成时为0). (2认同)
  • 它也适用于Python 2.7.10 (2认同)

99S*_*ono 8

myProcessIsRunning = poll() is None 
Run Code Online (Sandbox Code Playgroud)

正如主要答案所建议的那样,是检查进程是否正在运行的推荐方法和最简单的方法。(它也适用于 jython)

如果您手头没有流程实例来检查它。然后使用操作系统的TaskList/Ps 进程。

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

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

这基本上与以下命令行执行相同的操作:

cmd /c "tasklist /FI "PID eq 55588" | findstr 55588"
Run Code Online (Sandbox Code Playgroud)

在 linux 上,我使用以下命令完全相同:

pidStr = str(pid)
commandArguments = ['ps', '-p', pidStr ]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

请注意,如果您使用 VS Code 进行开发并使用纯 Python 和 Jython,请务必小心。在我的环境中,我错觉 poll() 方法不起作用,因为我怀疑肯定已经结束的进程确实正在运行。这个过程启动了 Wildfly。在我要求 Wildfly 停止之后,shell 仍在等待用户“按任意键继续......”。

为了完成这个过程,在纯 python 中,以下代码正在运行:

process.stdin.write(os.linesep)
Run Code Online (Sandbox Code Playgroud)

在 jython 上,我必须修复这段代码,使其看起来如下:

print >>process.stdin, os.linesep
Run Code Online (Sandbox Code Playgroud)

有了这种差异,这个过程确实完成了。jython.poll() 开始告诉我这个过程确实完成了。