python subprocess模块开启的子进程不随父进程一同结束问题解决

时间:2024-05-22 16:33:24

  最近用subprocess模块的Popen函数开启子进程,运行flask框架时出现一个问题,那就是调用subprocess模块的脚本运行结束后,在其fork出的子进程中运行的flask框架并未关闭,这就导致在开发阶段关闭该子进程十分麻烦,经过一番查找测试,通过使用wait()方法阻塞父进程或捕获关闭信号(ctrl+c)后关闭子进程便可轻易解决.

  首先我们来看看出现的问题,这是启动两个flask框架的脚本(至于python解释器要用绝对路径的方式写,那是因为subprocess.Popen函数就相当于在终端新开了一个窗口,即便你的脚本已经在指定虚拟环境或指定解释器下运行了,但是subprocess.Popen函数开启的子进程的运行环境和父进程无关,所以不指定解释器,直接用python启动程序的话,就相当于使用系统默认的python解释器运行程序)

#!/usr/bin/python
#-*- coding: utf-8 -*-
import subprocess

manage = subprocess.Popen("/home/lyz/.virtualenvs/videoframework_py2/bin/python2.7 video_server/video_server.py", shell=True)

yolo3 = subprocess.Popen("/home/lyz/.virtualenvs/python3_video/bin/python3.5 algorithm_server/algorithm_server.py ",shell=True)

  这是脚本运行结束后查找python相关进程的情况

python subprocess模块开启的子进程不随父进程一同结束问题解决

  可以看到,当python脚本运行结束后,我在另外一个终端查找python相关进程,该脚本启动的两个flask框架仍在运行,使得每次关闭子进程时还要查找进程号,再用kill -9 进程号的方法杀死子进程,十分麻烦,于是,使用子进程对象的wait()方法,阻塞父进程,从而在强制退出时使父进程报错,让父进程和子进程一同结束.这是改动之后的脚本.

#!/usr/bin/python
#-*- coding: utf-8 -*-
import subprocess
import signal
import sys

manage = subprocess.Popen("/home/lyz/.virtualenvs/videoframework_py2/bin/python2.7 video_server/video_server.py", shell=True)

yolo3 = subprocess.Popen("/home/lyz/.virtualenvs/python3_video/bin/python3.5 algorithm_server/algorithm_server.py ",shell=True)

ret=yolo3.wait()

  这是运行之后的结果,可以看到使用ctrl+c关闭脚本后,该脚本启动的两个flask框架也同时关闭了.

python subprocess模块开启的子进程不随父进程一同结束问题解决

       假如觉得上面的方法不够优雅,可以使用python的signal模块,捕获关闭信号(ctrl+c),再调用kill()或者terminate() 方法关闭子进程.代码如下:

#!/usr/bin/python
#-*- coding: utf-8 -*-
import subprocess
import signal
import sys

manage = subprocess.Popen("/home/lyz/.virtualenvs/videoframework_py2/bin/python2.7 video_server/video_server.py", shell=True)

yolo3 = subprocess.Popen("/home/lyz/.virtualenvs/python3_video/bin/python3.5 algorithm_server/algorithm_server.py ",shell=True)

# ret=yolo3.wait()

def signal_handler(signal, frame):
    # manage.kill()
    # yolo3.kill()
    manage.terminate()
    yolo3.terminate()

    sys.exit(0)

signal.signal(signal.SIGINT,signal_handler)
while True:
   pass

    这是运行之后的结果,可以看到使用ctrl+c关闭脚本后,该脚本启动的两个flask框架同样也同时关闭了,且没有任何报错.

python subprocess模块开启的子进程不随父进程一同结束问题解决