等待进程结束由名为

时间:2016-12-22 21:42:02

标签: python subprocess wait popen waitpid

我正在python中编写一个程序,它通过subprocess.Popen命令调用另一个程序。

被调用的程序启动用户与之交互的GUI,但在此之前它会通过一些服务来验证用户。

话虽如此,我正在试图找出一种方法来了解用户何时退出该GUI。基本上,我想等到GUI退出,然后继续我的程序。

我的问题是,由于我在实际启动GUI之前调用的程序会通过这些服务,看起来我调用的程序结束然后生成一个新的进程,即GUI,然后我无法等待pid,因为我的pid已经终止了。

我试过这个:

p = subprocess.Popen('/user/sbin/startprogramtolaunchgui')
p.wait()
printf 'done'

但是'完成'会立即打印出来,而不是在退出GUI之后。此外,当我运行命令

ps -ef

我调用的程序'startprogramtolaunchgui'不在进程列表中。但是,我看到它在进程列表中启动的gui(我要监视的那个)

修改

我想出了这个:

def isRunning(pid):
      try: 
         os.kill(pid, 0)
         return True
      except OSError:
         return False


 p = subprocess.Popen('/user/sbin/startprogramtolaunchgui')
 time.sleep(5)
 temp = subprocess.check_output(['pgrep', 'gui']) #get pid of GUI process

 while(isRunning(int(temp))):
      pass

print 'GUI CLOSED'

它有效......但这真的是一种可行的方法吗?

2 个答案:

答案 0 :(得分:1)

如果您使用p.wait(),则还应将stdout=PIPE作为Popen来电的参数。

另一种方法是使用p.communicate()为您自动调用wait()

无论哪种方式都应该有效。

答案 1 :(得分:0)

这是部分/暂定的答案。调查psutil库,其中包含用于查找给定进程的子进程以及等待进程完成的工具。这是一种方法草图。它有问题,但希望它为你提供了一个起点:

import psutil
parent = psutil.Process(p.pid)
procs = set([parent])
while parent.is_running():  # hmm, OK, but what if one of the children spawns a grandchild *after* the parent has finished... 
    for child in parent.children(recursive=True):
        procs.add(child)
    # Hmm, here we are busy-waiting

psutil.wait_procs(procs)

这是另一种可能解决孙子孙女问题的方法:

import psutil
procs = {psutil.Process(p.pid)}
while procs:
    procs = {proc for proc in procs if proc.is_running()}
    for proc in list(procs):
        for child in proc.children():
            procs.add(child)
    # Hmm, here we are busy-waiting

但是你可能仍然有'#34; reparenting"问题中指出了问题。上面的方法可能有用,或者你最好不要简单地从Python反复调用ps并解析它的文本输出,等待你的GUI进程出现的任何签名然后消失。