PySerial多Python脚本读取同一串口的干扰性及潜在问题咨询
两个PySerial脚本读取同一串口是否会互相干扰?
首先得说,你能测出两个脚本暂时正常运行,其实是踩中了Linux串口设备的默认行为,但确实藏着后续出问题的风险,我给你掰扯清楚:
当前能正常工作的原因
- Linux内核下的串口设备文件(比如
/dev/ttyACM1)默认是允许多个进程同时打开的,不像有些外设会强制排他锁,所以你两个脚本都能成功初始化串口连接。 - 串口的字节流会被内核复制到每个打开该设备的进程缓冲区里,所以短时间内、数据量不大的时候,每个进程都能拿到完整的行数据,看起来没啥问题。
后续可能出现的异常风险
别觉得现在没事就高枕无忧,这些坑很容易踩:
- 数据解析错误:如果串口数据量变大,或者树莓派系统负载升高,两个进程的
readline()可能会“拆分”同一段数据。比如一个进程刚读走换行符前的部分字节,另一个进程再读就拿到不完整的行,直接导致解码或业务逻辑出错。 - 全局参数冲突:要是其中一个脚本不小心修改了串口参数(比如波特率、奇偶校验),另一个脚本的读取会立刻失效——因为串口参数是全局的,改一次所有打开该端口的进程都会受影响。
- 资源泄漏:你的脚本完全没做异常处理,要是串口突然断开(比如Arduino断电),其中一个脚本崩溃时可能没正确释放串口文件描述符,时间久了可能会出现端口锁定、无法重新打开的情况。
更稳妥的解决方案
既然你想让两个脚本保持独立,又要避免风险,推荐两种思路:
思路1:单进程读数据,多模块处理
写一个单独的串口采集脚本,只负责从串口读取数据,然后在脚本内部启动两个线程(或者用队列),把数据分发给两个不同的处理逻辑。这样既保证了数据只被读取一次,又能让两个业务逻辑保持独立。
思路2:用中间件做数据转发
如果一定要把两个脚本完全分开,可以用轻量的中间层传递数据:
- 第一个脚本只做串口读取,把数据写入**命名管道(FIFO)**或者Redis缓存;
- 另外两个脚本分别从FIFO/Redis读取数据,执行各自的业务操作。
退而求其次:给现有脚本加防护
要是你暂时不想改架构,至少给每个脚本加上这些防护措施:
import serial import time try: # 加上超时时间,避免进程卡死在readline() ser = serial.Serial('/dev/ttyACM1', 115200, timeout=1) print("串口连接成功") while True: try: line = ser.readline().decode("utf-8").rstrip() if line: # 只处理非空数据行 ##do something## time.sleep(0.01) # 降低循环频率,减轻系统负载 except UnicodeDecodeError: print("读取到无效UTF-8数据,清空缓冲区") ser.flushInput() except serial.SerialException as e: print(f"串口异常: {str(e)}") break except serial.SerialException as e: print(f"无法打开串口: {str(e)}") finally: # 确保程序退出时关闭串口 if 'ser' in locals() and ser.is_open: ser.close() print("串口已关闭")
内容的提问来源于stack exchange,提问作者resolver101
相关产品推荐
相关产品推荐

