如何等待子进程的开始?

时间:2017-07-26 12:53:06

标签: python windows subprocess psutil

我执行一个进程(使用Popen),过了一会儿,这个进程执行一个子进程 我要做的是等待子进程生成,然后继续执行我的脚本。

我发现的唯一方法是使用psutil和轮询,直到进程有子进程。

process = psutil.Process(subprocess.Popen(command).pid)
while 0 == len(process.children()):
    time.sleep(0.2)

有没有比投票给孩子更好的方法呢?也许等待一些事件?

我正在使用Windows 10。

4 个答案:

答案 0 :(得分:1)

根据您的注释,您可以在启动其子进程时让您正在为STDOUT编写内容,您可以轻松地使用Popen.check_output()从父进程中获取STDOUT字符串。例如,如果您的子流程(command)写入STDOUT Subprocess started\n,您可以完全通过subprocess模块执行此操作:

import subprocess

response = subprocess.check_output(command)
if response.rstrip() == "Subprocess started":
    print("Woo! Our sub-subprocess was started...")

但是,如果您的command返回多个输出,则可能需要清除那些您不感兴趣的输出。您可以通过观察上述Subprocess started字符串的子进程'STDOUT来实现这一点。 ,像:

import subprocess

proc = subprocess.Popen(command, stdout=subprocess.PIPE)
while True:  # a loop to read our subprocess STDOUT
    line = proc.stdout.readline().rstrip()  # read line-by-line
    if line == "Subprocess started":
        print("Woo! Our sub-subprocess was started...")
        break  # no need to read the STDOUT anymore

如果您希望从command收到错误消息(例如无法启动子进程或类似内容),您也可以捕获STDERR(或将其传递给STDOUT)。

答案 1 :(得分:0)

我认为没有更好的解决方案。但您可以优化流程调用:

process = psutil.Popen(command)
  

Popen class

     

stdlib subprocess.Popen的更方便的接口。它启动一个子进程,你完全像使用subprocess.Popen时那样处理它,但是它还提供了psutil.Process类的所有方法。 [...]

此外,您可以使用wait函数编写自己的事件。等待是更多的CPU饥饿,但它更敏感。例如,请参阅here。但这取决于你的python版本。

答案 2 :(得分:0)

如果第一个孩子在产生自己的孩子后可以写东西,那么主脚本可以等待第一次写作。

这是一个工作示例(Windows上的环境Python 2.7):

Python主脚本:

python = r"C:\Python27\python.exe"
script = r"...\foo.py"
deb = time.clock()
child = subprocess.Popen([ python, script], stdout = subprocess.PIPE)
cr = child.stdout.read()
fin = time.clock()
print fin-deb, cr

Python(简化)第一个孩子:

time.sleep(2)  # add a delay
# the child is supposed to be spawned here
print "Done"
sys.stdout.flush()  # flushes stdout so that caller gets it immediately
time.sleep(8)       # just to make the child live a little longer

主脚本输出为:

2.12153148707 Done

证明主要脚本在第一次睡眠后继续。

答案 3 :(得分:0)

如果您可以控制子进程,则可以在父对象和子进程之间使用一些同步原语,例如使用套接字或文件,否则在繁忙循环中轮询children()是唯一可以执行的操作,只需确保在一段时间后退出while循环,否则您的程序可能会无限期地挂起。