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

Linux POSIX环境下消费者线程串口写导致程序运行一段时间后挂起咨询

问题根因

你遇到的挂起问题确实和串口侧的堵塞直接相关,核心原因有2个:

  1. 你开启了串口硬件流控CRTSCTS,如果串口对端没有及时读取数据,会通过流控信号阻止本地发送,此时串口的write调用会进入永久阻塞状态,且不会返回错误码。
  2. 你的代码逻辑错误导致串口发送冗余数据,加速了发送缓冲区耗尽:mq_receive返回的ret是实际收到的消息字节数,但你每次调用write时都写整个rcvBuffer的大小(82字节),额外多发送10字节的无效数据,快速占满串口默认的4KB左右发送缓冲区。
    你观察到的「修改MAX_MSG_SIZE后挂起前接收的消息数量变化」「刚好51次挂起」完全符合这个逻辑:按默认参数每次发送82字节计算,51次累计发送约4182字节,刚好打满4KB的串口发送缓冲区,后续write直接阻塞。

修复方案

  • 优先关闭硬件流控测试验证:将UartInit中tty->c_cflag |= CRTSCTS;改为tty->c_cflag &= ~CRTSCTS;,确认是否还会出现挂起问题,若必须使用流控则需要排查对端的流控信号逻辑。
  • 修复串口写逻辑:不要发送整个缓冲区,只发送实际收到的消息长度,将write(fd, rcvBuffer, sizeof(rcvBuffer))改为write(fd, rcvBuffer, ret)。
  • 修复宏定义优先级bug:将MSG_BUFFER_SIZE的定义改为#define MSG_BUFFER_SIZE (MAX_MSG_SIZE + 10),避免后续其他地方调用时出现运算符优先级错误。
  • 可选优化:如果允许数据丢失,可在打开串口时添加O_NONBLOCK标志将串口设为非阻塞模式,write返回EAGAIN错误时跳过本次发送或者做重试逻辑,避免线程永久挂起。
  • 可选优化:补充串口配置中缺失的VMIN参数,在tty.c_cc[VTIME] = 0;后添加tty.c_cc[VMIN] = 1;,避免后续串口读操作出现异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 09:39:02