Linux环境下管道传输数据出现卡顿不连贯问题如何解决?
问题根本原因
这不是管道的固有特性,是标准IO库的默认缓冲策略导致的:
- 当程序的标准输出指向交互式终端时,默认使用行缓冲,每输出一行遇到换行符就会自动刷新缓冲区,所以直接运行
python3 pipe_out.py时输出顺滑 - 当标准输出指向管道、文件这类非交互式设备时,默认使用全缓冲,只有缓冲区填满(通常为4KB/8KB)或者程序主动刷新缓冲区时才会输出数据,这就是成批输出、卡顿的核心原因。
管道场景下的修复方案
不需要更换通信方式,仅需要调整缓冲策略即可实现流畅输出:
无需修改源码的通用方案
使用Linux系统自带的stdbuf工具强制程序使用行缓冲模式,直接修改启动命令即可:
stdbuf -oL ./sercom | stdbuf -oL python3 main.py
其中-oL参数指定标准输出流使用行缓冲,每输出一行就自动刷新,该方案对绝大多数未自定义缓冲规则的二进制程序、Python脚本都生效。
如果是Python脚本也可以直接加-u参数开启无缓冲模式:
python3 -u pipe_out.py | python3 -u pipe_in.py
修改源码的方案
C语言串口程序
每次调用printf输出完一行传感器数据后,主动调用fflush(stdout)强制刷新缓冲区即可。
Python输出程序
调用print时添加flush=True参数:
print(n, 'testing lines out of 100000', flush=True)
替代进程间通信方案
如果需要更灵活的跨进程通信,可以选择以下低延迟方案,都能满足高频传感器数据的传输需求:
- Unix域套接字:传输效率高于TCP套接字,不需要走网络协议栈,支持流式数据传输,编程逻辑和串口读写差异很小
- 共享内存+信号量:延迟最低,适合传输超高频、大流量数据,需要自行实现数据同步逻辑
- FIFO命名管道:逻辑和匿名管道基本一致,支持无父子关系的进程间通信,同样需要注意配置缓冲策略
内容的提问来源于stack exchange,提问作者Cronos
相关产品推荐
相关产品推荐

