Python 2.7多进程传值:Flask进程与子进程数据交互问题
解决Flask进程与子进程间的数据传递问题
嘿,我来帮你搞定这个进程间数据传递的问题!你遇到的坑其实很多人都踩过,我给你拆解下原因,再给你几个靠谱的解决方案:
为什么你之前的方法行不通?
- 全局变量失效:多进程模式下,每个进程都有独立的内存空间。你在子进程里修改的
globalvar只是它自己内存里的副本,和Flask进程里的globalvar完全是两个东西,自然看不到变化。 - Flask放线程无响应:大概率是没处理好线程启动逻辑,或者不小心开了Flask的debug模式——debug模式默认会启动两个进程,这时候线程里的全局变量还是会失效;另外如果主线程直接退出,子线程里的Flask还没启动就跟着结束了,也会导致无响应。
方案1:用Queue实现进程间安全通信
队列是Python多进程中最常用的通信方式,它自带进程安全机制,不用担心数据竞争。你已经导入了Queue,只是没用到,直接看代码:
from flask import Flask from multiprocessing import Process, Queue import time app = Flask(__name__) # 初始化一个队列,用来在进程间传递数据 data_queue = Queue() @app.route('/') def index(): # 取出队列里的最新值(循环取空确保拿到最后一个更新) current_val = 0 while not data_queue.empty(): current_val = data_queue.get() return f"当前值: {current_val}" def multiprocess_task(q): i = 0 while True: # 把新值放入队列 q.put(i) print(f"子进程更新值为: {i}") i += 1 time.sleep(1) if __name__ == '__main__': # 启动子进程,把队列传进去 p = Process(target=multiprocess_task, args=(data_queue,)) p.daemon = True # 设置为守护进程,主进程退出时自动结束 p.start() # 启动Flask app.run(host='0.0.0.0', port=5000)
方案2:用Value共享单一数值(更高效)
如果只是传递单一数值类型的数据,用multiprocessing.Value更直接,它是基于共享内存实现的,性能比队列好:
from flask import Flask from multiprocessing import Process, Value import time import ctypes app = Flask(__name__) # 创建一个进程共享的整数变量,初始值为0 shared_var = Value(ctypes.c_int, 0) @app.route('/') def index(): # 访问共享变量需要用.value属性 return f"当前共享值: {shared_var.value}" def multiprocess_task(var): i = 0 while True: var.value = i print(f"子进程更新共享值为: {i}") i += 1 time.sleep(1) if __name__ == '__main__': p = Process(target=multiprocess_task, args=(shared_var,)) p.daemon = True p.start() app.run(host='0.0.0.0', port=5000)
如果非要用线程实现?
如果你想换回线程模式,一定要注意关闭Flask的debug模式(debug模式会启动多进程,导致全局变量失效),同时确保主线程保持运行:
from flask import Flask from threading import Thread import time app = Flask(__name__) globalvar = 0 @app.route('/') def index(): return f"globvar in index={globalvar}" def update_var(): global globalvar i = 0 while True: globalvar = i print(f"更新globalvar为: {i}") i += 1 time.sleep(1) if __name__ == '__main__': # 启动更新变量的线程 t = Thread(target=update_var) t.daemon = True t.start() # 务必关闭debug模式! app.run(host='0.0.0.0', port=5000, debug=False)
内容的提问来源于stack exchange,提问作者Saim Neftci
相关产品推荐
相关产品推荐

