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

串口文件描述符调用close()出现30秒延迟,如何配置取消该关闭延迟?

问题根因

Linux 系统下串口文件描述符默认关闭时,会等待内核发送缓冲区的所有数据全部完成硬件传输才会返回。如果串口链路异常(如硬件断连、对端流控未放开导致数据无法发送),发送队列数据长期无法排空,close 调用就会阻塞,最长可达30秒,这是串口驱动的默认行为。

解决方法

  • 首先修正现有关闭代码的语法错误
    你当前代码中的 tcflush 调用缺少参数分隔符,未正常生效,正确写法如下:
tcflush(com_port->port_handle_, TCIOFLUSH);

TCIOFLUSH 会直接丢弃串口收发两端的所有内核缓冲区数据,无需等待未发送的数据传输完成,修复后大部分场景下 close 就不会再阻塞。

  • 临时配置文件描述符为非阻塞模式
    如果修复后仍有阻塞,可以在调用 close 前临时将文件描述符设为非阻塞模式,非阻塞模式下的 close 不会等待缓冲区排空,会直接返回:
int CloseSerialPort(SerComPort* com_port)
{
  if(com_port->port_handle_ > 0)
  {
     // 临时设置非阻塞
     int flags = fcntl(com_port->port_handle_, F_GETFL, 0);
     fcntl(com_port->port_handle_, F_SETFL, flags | O_NONBLOCK);
     // 清空缓冲区
     tcflush(com_port->port_handle_, TCIOFLUSH);
  }
  return close(com_port->port_handle_);
}

如果你的业务不影响正常收发逻辑,也可以在 open 串口时直接加上 O_NONBLOCK 标志:
fd = open(addr, O_RDWR | O_NONBLOCK);
注意这种情况下正常读写串口时需要处理 EAGAIN 错误码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:06:00