我正在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'
它有效......但这真的是一种可行的方法吗?
答案 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进程出现的任何签名然后消失。