![](/img/trans.png)
[英]python 3.5 - subprocess.run still running after the script was terminated
[英]Python subprocess script keeps running after it is done
在我的一个Django视图中,我调用python脚本并获取其pid:
from subprocess import Popen
p = Popen(['python', 'script.py'])
mypid = p.pid
当试图找出进程是否仍在从另一个页面运行时,我在mypid
上使用以下函数(感谢这个问题 ):
def doesProcessExist(pid):
if pid < 0:
return False
try:
os.kill(pid, 0)
except OSError, e:
return e.errno == errno.EPERM
else:
return True
无论我等待多久, 该过程仍然显示为正在运行 。 唯一阻止它的是,如果我用Popen生成一个新的python脚本进程。 无论如何我可以解决这个问题吗? 我不确定这是否是由于Django在脚本完成后没有正确关闭python或其他原因造成的。 在Ubuntu的进程状态管理器中,该进程显示为[python] <defunct>
。
-
对于我尝试过的所有script.py
,问题都是正确的。 我目前正在使用一个简单的:
from time import sleep
sleep(5)
真的,你在做什么是错的。 当您使用像subprocess.Popen
这样的高级包装器时,您需要通过该对象管理进程。 在其他地方拥有PID并不足以管理它。
如果你坚持处理PID而不是Popen
对象,那么你应该在os
使用低级API。
幸运的是,你没有做任何复杂的事情,比如创建管道来与子进程交谈。 因此,您可以使用您最喜欢的spawn
变体启动它,然后使用waitpid
或其中一个变体等待它。
我假设您在单进程Web服务器中执行此操作。 如果您正在使用分叉Web服务器,其他页面可能处于不同的进程中,即使使用PID也无法正常工作。 父进程必须收获子进程,而不是其他任意进程。 如果你想做这项工作,你将不得不让事情变得更复杂,而且你真的必须先了解Unix流程模型才能向任何人解释。
你看到的是一个僵尸进程。 它不会继续运行。 它不能。 它死了。 唯一剩下的就是一些允许相关进程检索其状态的信息。
要查明子p.poll()
是否处于活动状态而不阻塞,请调用p.poll()
。 如果它返回None
那么进程仍处于活动状态,否则你可以安全地忘记它(它已经被.poll()
)。
subprocess
进程模块调用_cleanup()
函数来_cleanup()
Popen()
构造函数中的僵尸进程。 所以通常你的脚本不会创建很多僵尸进程。
要查看僵尸进程列表:
import os
#NOTE: don't use Popen() here
print os.popen(r"ps aux | grep Z | grep -v grep").read(),
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.