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

如何用Python serial解决多线程读写串口的数据损坏问题?

多线程串口操作的线程安全处理方案

场景与问题

  • 场景:一个线程通过USB串口每秒轮询温度传感器10次;用户按下按钮时,主线程通过同一串口修改传感器模式。
  • 问题:change_sensor_mode()的串口写入操作可能打断轮询线程的write/read_until操作,导致串口数据错乱。

原始示例代码

import threading, serial, time

serial_port = serial.Serial(port="COM2", timeout=1.0)

def poll_temperature():
    while True:
        serial_port.write(b"GETTEMP\r\n")
        recv = serial_port.read_until(b"END")
        print(recv)
        time.sleep(0.2)

def change_sensor_mode():
    serial_port.write(b"CHANGEMODE2\r\n")

t1 = threading.Thread(target=poll_temperature)
t1.start()

time.sleep(4.12342)  # 模拟等待用户输入

change_sensor_mode()

手动锁尝试(非标准实现)

我曾尝试用全局变量手动控制锁状态,让主线程等待轮询操作完成:

global lock

def change_sensor_mode():
    elapsed = 0
    t0 = time.time()
    while lock and elapsed < 1.0:
        time.sleep(0.010)
        elapsed += 0.010
    serial_port.write(b"CHANGEMODE2\r\n")

标准解决方案:使用threading.Lock

Python标准库的threading.Lock是处理多线程资源竞争的专用工具,能保证同一时间只有一个线程访问串口资源,且自动管理锁的获取与释放,避免手动控制的疏漏。

优化后的代码

import threading, serial, time

serial_port = serial.Serial(port="COM2", timeout=1.0)
lock = threading.Lock()  # 创建全局锁对象

def poll_temperature():
    while True:
        # 使用with语句自动获取/释放锁,确保串口操作原子性
        with lock:
            serial_port.write(b"GETTEMP\r\n")
            recv = serial_port.read_until(b"END")
        print(recv)
        time.sleep(0.2)

def change_sensor_mode():
    # 同样用with包裹串口写入操作
    with lock:
        serial_port.write(b"CHANGEMODE2\r\n")

t1 = threading.Thread(target=poll_temperature)
t1.start()

time.sleep(4.12342)  # 模拟等待用户输入

change_sensor_mode()

带超时处理的进阶实现

如果需要在获取锁超时后给出提示,可以用acquire()方法手动控制锁:

def change_sensor_mode():
    # 尝试1秒内获取锁,失败则放弃
    if lock.acquire(timeout=1.0):
        try:
            serial_port.write(b"CHANGEMODE2\r\n")
        finally:
            lock.release()  # 无论是否异常,确保释放锁
    else:
        print("获取串口锁超时,无法修改传感器模式")

方案优势

  • 自动管理锁生命周期,避免手动设置lock变量时可能出现的死锁或锁未释放问题
  • 保证串口的读写操作是原子性的,不会被其他线程打断
  • 支持超时控制,灵活处理资源竞争场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 06:05:29