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

Python多线程监听双串口数据丢失问题排查与解决

串口双线程监听数据丢失问题的原因与解决办法

问题原因分析

  • 普通列表非线程安全:你使用的data_queue是普通Python列表,多线程同时调用append()和pop(0)时会触发数据竞争,比如两个线程同时追加数据可能导致元素覆盖、队列结构损坏,直接造成数据丢失。
  • CPU资源抢占导致串口读取不及时:主线程的while True忙轮询会占用大量CPU资源,使得串口监听线程得不到足够时间片去读取串口缓冲区数据,当缓冲区满溢后,新传入的数据就会被丢弃。
  • 串口读取逻辑存在缺陷:如果read_serial()是单次读取固定长度数据,或者未处理缓冲区剩余数据,线程频繁切换时会导致部分数据留在缓冲区未被读取,最终溢出丢失。

解决方案及优化代码

1. 核心优化点

  • 用线程安全的queue.Queue替代普通列表,避免多线程竞争问题。
  • 主线程改用queue.get()阻塞等待数据,不再占用多余CPU资源。
  • 优化串口读取逻辑,确保及时清空缓冲区,避免数据残留。

优化后的完整代码

import threading
import queue
import serial  # 假设使用pyserial库操作串口

# 初始化线程安全队列
data_queue = queue.Queue()

def serial_listener(port, tag):
    # 根据设备实际参数配置串口
    ser = serial.Serial(port=port, baudrate=9600, timeout=0.1)
    try:
        while True:
            # 读取缓冲区所有数据,避免残留
            data = ser.read_all()
            if data:
                # 转码后加入队列(编码格式按需调整)
                data_queue.put([data.decode('utf-8'), tag])
    except Exception as e:
        print(f"串口{port}异常: {e}")
    finally:
        ser.close()

if __name__ == "__main__":
    # 创建守护线程,主线程退出时自动终止子线程
    thread_usb0 = threading.Thread(target=serial_listener, args=('/dev/ttyUSB0', "1"), daemon=True)
    thread_usb1 = threading.Thread(target=serial_listener, args=('/dev/ttyUSB1', "2"), daemon=True)
    
    thread_usb0.start()
    thread_usb1.start()

    # 主线程阻塞等待队列数据,无需忙轮询
    while True:
        new_data = data_queue.get()  # 无数据时自动阻塞,不占用CPU
        print("*****New data has arrived.*****")
        print(new_data)
        if new_data[1] == "1":
            # 执行串口1的后续处理逻辑
            pass
        elif new_data[1] == "2":
            # 执行串口2的后续处理逻辑
            pass
        else:
            print("未知端口标签")

额外注意事项

  • 确保串口参数(波特率、奇偶校验、数据位等)与设备端完全一致,参数不匹配也会导致数据乱码或丢失。
  • 若数据量极大,可设置队列最大容量(queue.Queue(maxsize=N)),避免内存占用过高。
  • 不要使用join()阻塞主线程,你的场景下守护线程的方式更适配主线程持续运行的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:26:37