[英]Terminating subprocess in python
根据我自己的调查完全重写
我有一个运行许多其他python脚本的主脚本。 脚本创建为
from subprocess import STDOUT, Popen
from signal import SIGINT
import shlex
p = Popen(shlex.split("python somescript.py arg1 arg2"), cwd="../src/somedir", stderr=STDOUT)
并以终止
p.send_signal(SIGINT)
p.wait()
在他们里面有下面的代码
if __name__ == "__main__":
import signal
def terminate(*args):
raise KeyboardInterrupt
signal.signal(signal.SIGINT, terminate)
# do some work here
每个脚本都有一些功能
try:
# create workers
except KeyboardInterrupt:
# cleanup, wait for the current worker to end, then return
所有描述的工作均按预期进行-主脚本创建进程,执行结束后,将其发送给SIGINT,它们以正确的方式进行处理,并正常退出。
现在,我想以相同的方式运行Django开发服务器。
我更改了manage.py
文件:
if __name__ == "__main__":
import signal
def terminate(*args):
print 'got SIGINT'
raise KeyboardInterrupt
signal.signal(signal.SIGINT, terminate)
execute_manager(settings)
多次调用后, execute_manager
函数导致django命令方法具有sys.exit(0)
except KeyboardInterrupt
块。 因此,整个设置看起来相同。
问题:虽然我看到got SIGINT
输出,但django服务器实际上并未停止。
可能是一个解释:
看起来像django manage.py本身分叉,或执行类似操作; 查看Activity Monitor(osx的进程浏览器),我看到启动了3个python进程-一个用于主脚本,可能还有2个用于manage.py。 终止时,其中两个停止(主脚本,而我具有p
的链接),而第三个仍然继续锁定8000端口。 有没有一种方法来获取流程的子流程pid?
您可以使用psutil来查找有关子进程的信息,例如使用伪代码:
p = Popen(...)
pp = psutil.Process(p.pid)
for child in pp.get_children():
child.send_signal(signal.SIGINT)
注意在不使用--reload的情况下(使用ps -ef | grep manage.py | grep -v grep
ps -ef | grep manage.py | grep -v grep
ps -ef | grep manage.py | grep -v grep
:
vinay 7864 7795 9 22:10 pts/0 00:00:00 python ./manage.py runserver
vinay 7865 7864 16 22:10 pts/0 00:00:00 /usr/bin/python ./manage.py runserver
与使用--noreload选项相比:
vinay 7874 7795 7 22:10 pts/0 00:00:00 python ./manage.py runserver --noreload
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.