简体   繁体   English

等待进程结束由进程调用创建的进程

[英]Wait for a process to end that is created by a process called

I'm writing a program in python which calls another program via the subprocess.Popen command. 我正在python中编写一个程序,它通过subprocess.Popen命令调用另一个程序。

The program being called launches a GUI that the user interacts with, but before that it goes through some services to authenticate the user. 被调用的程序启动用户与之交互的GUI,但在此之前它会通过一些服务来验证用户。

With that being said, I'm trying to figure out a way to know when the user exits out of that GUI. 话虽如此,我正在试图找出一种方法来了解用户何时退出该GUI。 Basically, I want to wait until the GUI is exited, and then continue in my program. 基本上,我想等到退出GUI,然后继续我的程序。

My problem is that since the program I make a call to goes through those services before the GUI is actually launched, it seems like the program I make a call to ends and then spawns a new process which is the GUI, and then 'm not able to wait on the pid because the pid I have as already terminated. 我的问题是,因为在实际启动GUI之前,我调用的程序会通过这些服务,看起来我调用的程序结束然后生成一个新的进程,即GUI,然后不是能够等待pid,因为我已经终止了pid。

I have tried this: 我试过这个:

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

But 'done' gets printed right away, not after the GUI is exited out of. 但是'完成'会立即打印出来,而不是在退出GUI之后。 Also, when I run the command 另外,当我运行命令时

ps -ef

The program 'startprogramtolaunchgui' I called is not in the process list. 我调用的程序'startprogramtolaunchgui'不在进程列表中。 BUT, I see the gui that it launched in the process list (the one that I want to monitor) 但是,我看到它在进程列表中启动的gui(我要监视的那个)

EDIT: 编辑:

I came up with this: 我想出了这个:

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'

It works...but is this really an okay way to do it?? 它有效...但这真的是一个好的方法吗?

If you use p.wait() you should also include stdout=PIPE as an argument to Popen call. 如果你使用p.wait()你还应该包括stdout=PIPE作为Popen调用的参数。

An alternative is to use p.communicate() which automatically calls wait() for you. 另一种方法是使用p.communicate()自动为您调用wait()

Either way should work. 无论哪种方式都应该有效。

This is a partial/tentative answer. 这是部分/暂定的答案。 Investigate the psutil library, which has tools for finding out the child processes of a given process, and for waiting for processes to finish. 调查psutil库,该库具有用于查找给定进程的子进程以及等待进程完成的工具。 Here is a sketch of an approach. 这是一种方法草图。 It has problems, but hopefully it gives you a starting point to work from: 它有问题,但希望它为您提供了一个起点:

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)

Here is another approach that may work around the grandchild-of-dead-grandparent problem: 这是另一种可能解决孙子孙女问题的方法:

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

But you may still have the "reparenting" problem pointed out in the comments. 但是你可能仍然有评论中指出的“重新定位”问题。 The above approaches may work, or you may be better off simply calling ps repeatedly from Python and parsing its text output, waiting for whatever signature your GUI process has there to appear and then disappear. 上面的方法可能会起作用,或者你最好不要简单地从Python中反复调用ps并解析它的文本输出,等待你的GUI进程出现的任何签名然后消失。

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

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