You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask使用subprocess调用外部py脚本 停止时如何获取回调数据

Flask子进程回调获取数组解决方案

核心问题:你当前直接调用process.kill()会强制发送SIGKILL信号终止子进程,子进程内存中的数据未做持久化/输出就被系统回收,无法直接获取,需要通过信号捕获+进程间通信机制实现需求,以下是改动最小的实现方案:


实现步骤

  1. 改造被调用的test.py:注册终止信号监听器,收到终止信号时将数组序列化后输出到标准输出再主动退出
  2. 改造Flask主程序:启动子进程时绑定标准输出管道,停止时发送可被捕获的SIGTERM信号,等待子进程退出后读取标准输出内容反序列化为数组

完整代码示例

1. test.py 代码

import signal
import json
import sys
import time

# 替换为你实际生成的数组
my_array = []

# 模拟业务逻辑:持续生成数组元素
def run_business():
    global my_array
    count = 0
    while True:
        my_array.append(count)
        count += 1
        time.sleep(1)

# 信号处理函数:收到终止信号时输出数组
def on_terminate(signum, frame):
    # 序列化数组输出到标准输出
    print(json.dumps(my_array))
    # 强制刷新缓冲区避免数据残留
    sys.stdout.flush()
    sys.exit(0)

# 注册SIGTERM信号监听
signal.signal(signal.SIGTERM, on_terminate)

if __name__ == "__main__":
    run_business()

2. Flask主程序代码

from flask import Flask, render_template, request, redirect, url_for
import subprocess
import json

app = Flask(__name__)
# 测试用全局变量存储子进程,生产环境请改用Redis/数据库存储
process = None

@app.route('/', methods=['POST', 'GET'])
def main():
    global process
    result_array = None
    if request.method == 'POST':
        index = request.form['index']
        if index == 'start':
            # 启动子进程时绑定标准输出管道
            process = subprocess.Popen(
                ['python', 'test.py'],
                stdout=subprocess.PIPE,
                text=True
            )
        if index == 'stop' and process is not None:
            # 发送SIGTERM信号触发子进程的善后逻辑,不要用kill
            process.terminate()
            # 等待子进程正常退出
            process.wait()
            # 读取子进程输出的数组数据
            output = process.stdout.read()
            if output:
                result_array = json.loads(output)
                # 此处可做存储、返回前端等后续操作
                print(f"获取到的子进程数组:{result_array}")
            process = None
        return redirect(url_for('main'))
    # 数组可直接传入模板渲染给前端
    return render_template('index.html', array=result_array)

if __name__ == "__main__":
    app.run(debug=True)

注意事项

  • Windows系统不支持SIGTERM信号,可改用SIGBREAK,或换用临时文件方案:子进程定时将数组写入临时文件,停止后主进程直接读取临时文件即可
  • 生产环境多worker部署时不要用全局变量存储process对象,可改用Redis缓存存储进程PID和通信标识
  • 数组体积较大时可改用pickle做二进制序列化,传输效率更高

内容的提问来源于stack exchange,提问作者Dmitry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:36:03