2017-04-12 75 views
0

我有一个处理请求的应用程序(使用2.7)。当收到“A”类型的请求时,我需要启动一个外部进程。Python外部进程没有终止

当收到类型“B”的请求时,我需要检查并看看外部进程是否已完成,然后根据它是否已完成做一些事情。

我遇到的问题是,当外部过程完成时不退出,它会变成僵尸状态,例如:

1 Z root  13703 13644 0 80 0 -  0 exit 09:37 ? 00:00:00 [python] <defunct> 

最初我开始用POPEN这样的过程:

DEVNULL = open(os.devnull, "wb") 
subprocess.Popen(cmd+args, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True) 

我尝试使用os.spawn:

os.spawnv(os.P_NOWAIT, 'python', cmd+args) 

但仍然过程中没有 出口。

任何人都知道我可以如何获得外部进程终止时完成?

+0

提供有关'外部process'一些信息。 – stovfl

+0

看起来问题在于你的外部进程,而不是启动它的Python程序。完成后是否关闭? –

回答

4

一个进程成为僵尸,直到其父进程收回它。你可以阅读有关如何/为什么一个过程变为https://unix.stackexchange.com/questions/105998/why-process-program-becomes-zombie

对于你的情况僵尸,你首先应该保持一个变量创建POPEN()对象的详细信息,然后就可以在该对象上调用的poll()检查当它完成执行时。一旦你调用poll()并且如果该子进程已经完成执行(即,达到了僵尸状态),那么poll()将自动清理该子进程。

p = subprocess.Popen(cmd+args, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True) 

在收到请求的B,你可以做

p.poll() 

这将返回过程的返回码或None如果还没有完成。

关于不同的功能,你可以POPEN对象调用的更多信息:https://docs.python.org/2/library/subprocess.html#popen-objects

+0

是的,这是问题所在。我无法保存Popen()对象,因为我的持久性存储是数据库。但我确实保存了pid,所以我可以在'os.waitpid()'中使用它。非常感谢! –