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

Flask集成pyserial打开COM7端口报错SerialException问题咨询

问题排查与解决方案

核心原因

  • Flask debug模式默认开启重载器:debug=True时Flask会启动2个进程(主进程+代码热重载进程),串口属于系统独占资源,第一个进程占用COM7后,第二个进程再尝试打开就会抛出端口占用异常,这是最核心的触发原因。
  • 串口初始化逻辑错误:你将serial.Serial实例化放在了serial_start函数内,且该函数被绑定到/路由的处理逻辑中,每次访问/路径都会重新尝试打开一次已经被占用的串口,也会触发报错。
  • 串口监听逻辑阻塞服务:serial_start内部是死循环,直接放在Flask请求处理函数中会永久阻塞当前请求,甚至拖垮整个Web服务的响应能力。

对应解决方案

  1. 关闭Flask重载器或者禁用debug模式:启动服务时添加use_reloader=False参数,避免多进程重复抢占串口。
  2. 全局初始化串口:将串口实例放在全局位置,确保服务生命周期内只打开一次串口。
  3. 用独立后台线程运行串口监听逻辑:不要占用Flask的请求处理线程运行死循环监听任务。

修正后可运行代码

from flask import Flask, request, render_template, Response
import serial
import threading

main = Flask(__name__)
# 全局初始化串口,仅执行一次
ser = serial.Serial('com7', 9600)
stop_flag = False

def serial_start():
    while not stop_flag:
        if ser.readable():
            res = ser.readline()
            res_decode = res.decode().strip()
            print(res_decode)

@main.route('/')
def hello_fnc():
    return 'Hello'

@main.route('/page', methods = ["GET", "POST"])
def page_fnc():
    if request.method == "POST":
        return 'POST received'
    else:
        return render_template("index.htm")

if __name__ == '__main__':
    # 启动串口监听后台线程
    serial_thread = threading.Thread(target=serial_start, daemon=True)
    serial_thread.start()
    # 关闭重载器,避免多进程抢占串口
    main.run(debug=True, use_reloader=False)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:06:03