Flask多进程运行永久函数问题:树莓派LED闪烁进程无法终止
故障原因及修复方案
核心错误点
- 子进程创建逻辑错误:你创建Process时给
target参数传了blink_lights(),加括号会直接在当前Flask请求的主进程中同步执行这个死循环函数,根本没有创建新的子进程,请求会直接卡死在死循环里,后续的停止逻辑完全无法触发,自然停不掉闪烁。 - Flask debug模式的重载机制冲突:debug模式默认会启动两个进程(一个用于代码热重载,一个是服务主进程),会导致multiprocessing的子进程管理混乱,出现子进程找不到、杀不掉的问题。
- 冗余的pigpio初始化:你把
initialise_pins放在了index路由中,每次访问首页都会重复初始化pigpio库,容易引发资源冲突。
修复方案
1. 修正子进程创建逻辑
把创建Process的代码改为传递函数引用(不加括号):
if action == "blink": # 只传函数名,不要加括号执行 p = Process(target=blink_lights, args=(), daemon=True) p.start()
2. 修复Flask启动参数
关闭debug模式的热重载,避免多进程干扰:
if __name__ == "__main__": # 增加use_reloader=False关闭热重载,防止双进程问题 app.run(host='0.0.0.0', port=8080, debug=True, use_reloader=False)
3. 优化pigpio初始化逻辑
把pigpio初始化从index路由移到程序启动阶段,只执行一次:
light_functions = ctypes.CDLL('./light_function.so') LED_1 = 13 LED_2 = 19 # 程序启动时只初始化一次引脚 light_functions.initialise_pins(LED_1, LED_2)
4. 可选优化:用全局变量管理闪烁进程
避免误杀其他子进程,控制逻辑更可靠:
# 全局变量存储当前的闪烁进程 blink_process = None @app.route('/<action>') def action(action): global blink_process LED_1_Status = 'Off' LED_2_Status = 'Off' if action == 'turn_on': light_functions.turn_on_lights(LED_1, LED_2) if action == 'turn_off': light_functions.clear_all(LED_1, LED_2) if action == "blink": # 先停掉之前的闪烁进程,避免重复创建 if blink_process and blink_process.is_alive(): blink_process.terminate() blink_process = Process(target=blink_lights, daemon=True) blink_process.start() if action == "stop_blink": if blink_process and blink_process.is_alive(): blink_process.terminate() light_functions.clear_all(LED_1, LED_2) # 停止后主动把灯关掉 if light_functions.light_status(LED_1): LED_1_Status = 'On' if light_functions.light_status(LED_2): LED_2_Status = 'On' templateData = { 'title': 'GPIO output Status!', 'LED_1': LED_1_Status, 'LED_2': LED_2_Status } return render_template('index.html', **templateData)
内容的提问来源于stack exchange,提问作者Ziv Ofir
相关产品推荐
相关产品推荐

