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

Rust tokio_serial中readable()不阻塞致CPU占用100%问题排查

tokio_serial接收数据后CPU占用100%的问题分析与解决

你的代码核心问题在于:当port.try_read()返回WouldBlock错误(即当前无有效可读数据,但之前的可读事件被触发)时,你直接忽略错误进入下一次循环,导致port.readable().await反复立即返回,形成无限空循环,CPU被拉满。

问题根源

串口的就绪通知(readable)在某些场景下会持续触发,比如第一次读取后驱动未正确清除就绪状态,或者try_read未完全消费就绪事件。此时如果不处理WouldBlock错误,循环会无休无止地执行readable().await和try_read(),完全占用CPU资源。

解决方案

最简洁可靠的方式是使用tokio::io提供的异步读写扩展方法,它们会自动处理等待就绪、重试等逻辑,无需手动管理readable()状态。

修正后的代码

use std::{env, process, str};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio_serial::{self, SerialPortBuilderExt};

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let baud_rate: u32 = 115200;
    let serial_port = env::args().nth(1).unwrap_or_else(|| String::from("/dev/ttyUSB0"));
    println!("Open port {serial_port}");

    let mut port = tokio_serial::new(serial_port, baud_rate)
        .open_native_async()
        .unwrap_or_else(|e| {
            println!("Error: {:?}", e);
            process::exit(-1);
        });

    let mut buf: [u8; 255] = [0; 255];
    loop {
        match port.read(&mut buf).await {
            Ok(size) if size > 0 => {
                println!("Got {} bytes: {}", size, str::from_utf8(&buf[0..size]).unwrap());
                // 使用write_all确保所有数据写入,避免部分写入
                if let Err(e) = port.write_all(&buf[0..size]).await {
                    println!("Write error: {:?}", e);
                }
            }
            Ok(0) => {
                // 串口连接关闭
                println!("Serial port closed");
                break;
            }
            Err(e) => {
                println!("Read error: {:?}", e);
                // 根据需求选择重试或退出
                // break;
            }
        }
    }
}

关键改进点

  1. 使用AsyncReadExt::read替代手动管理就绪状态:read().await会自动等待串口可读,直到有数据或发生错误,不会出现空循环。
  2. 使用AsyncWriteExt::write_all替代write:异步场景下write可能只写入部分数据,write_all会自动处理剩余数据的写入,确保数据完整发送。
  3. 明确处理各种返回情况:包括读取到0字节(连接关闭)和读取错误,避免静默忽略问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:37:50