Python类实例执行后销毁,无法终止Flask子进程问题求助
解决方案
核心思路
把Flask子进程的管理逻辑封装成类,让主进程持有类实例的引用(避免实例被销毁),同时在类中实现启动、停止方法,再通过注册退出钩子确保主进程终止时同步终止子进程。Windows下通过设置CPU亲和性实现核心独占。
代码修改
1. 重构flaskSubprocess.py为类管理模式
import subprocess import sys import psutil from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return "Hello from Flask!" def run_flask(): # 必须关闭debug模式,否则Flask会自动启动子进程,导致亲和性设置失效 app.run(host='0.0.0.0', port=5000, debug=False) class FlaskSubprocessManager: def __init__(self): self.flask_process = None def start_server(self, core_id=0): # 启动Flask子进程,创建独立进程组(Windows下方便批量终止) self.flask_process = subprocess.Popen( [sys.executable, '-c', 'from flaskSubprocess import run_flask; run_flask()'], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP ) # 设置子进程独占指定核心 proc = psutil.Process(self.flask_process.pid) proc.cpu_affinity([core_id]) # 传入单个核心ID,比如0号核心 print(f"Flask子进程启动,PID: {self.flask_process.pid},绑定核心: {core_id}") def stop_server(self): if self.flask_process and self.flask_process.poll() is None: # Windows下发送CTRL_BREAK_EVENT终止整个进程组 self.flask_process.send_signal(subprocess.CTRL_BREAK_EVENT) self.flask_process.wait() print("Flask子进程已终止")
2. 修改main.py保留实例并注册退出钩子
import atexit from flaskSubprocess import FlaskSubprocessManager # 全局保留实例,避免被垃圾回收 flask_manager = FlaskSubprocessManager() def cleanup_flask(): flask_manager.stop_server() if __name__ == "__main__": # 启动Flask子进程,绑定到0号核心(可根据需要修改核心ID) flask_manager.start_server(core_id=0) # 注册退出钩子:主进程终止时自动停止Flask子进程 atexit.register(cleanup_flask) # 主进程业务逻辑示例 try: input("按Enter键终止主进程...\n") except KeyboardInterrupt: pass
关键说明
- 保留实例引用:通过全局变量保存
FlaskSubprocessManager实例,避免函数调用后实例被销毁,确保随时能调用stop_server。 - 核心独占:使用
psutil的cpu_affinity方法,限制子进程仅在指定核心运行(Windows系统有效),需先安装psutil:pip install psutil。 - 进程终止:创建子进程时使用
CREATE_NEW_PROCESS_GROUP,配合CTRL_BREAK_EVENT信号可一次性终止Flask相关的所有进程,避免残留。 - 自动清理:通过
atexit.register注册清理函数,无论主进程是正常退出还是被中断,都会自动调用stop_server终止Flask子进程。
内容的提问来源于stack exchange,提问作者sharkyenergy
相关产品推荐
相关产品推荐

