rust中的超时处理

rust中的超时处理 

自从 tokio 1.0发布以来,rust的异步开发总算大势已定。尽管没达到标准库的速度,依然挡不住大家的热情。看编程排行榜,增加2倍的开发者。

既生瑜何生亮,感觉go就是小号的rust。

不废话了。背景:之前用go开发一个边缘网关的小东东,业余时间做了一大半。后来学了rust,打算练手,用rust重新写。

在crate中央仓库里找来找去,选择了 tokio-modbus。测试中发现用rtu的方式下,如果slave没有发回数据,程序将陷入无限等待中。也没找到如何设置这个超时。串口配置中倒是有个超时设置,不知道有啥用。

在tokio-modbus的github上,找到有人提到这个问题。那个解决问题的方式实在是理解不了,也很啰嗦。

自己动手, 用golang和tokio中都有的 select 很好的解决问题。

核心代码如下

1 tokio::select! {
2     result = &ctx.read_holding_registers(3,12) => match result {
3         Ok(v) => println!("Reading holding {:?}", v),
4         Err(_) => println!("reading err"),
5     },
6     _ = tokio::time::sleep(std::time::Duration::from_millis(100)) => println!("reading timeout 100 ms"),
7 }

完整的测试代码如下

use tokio_modbus::prelude::Reader;
use tokio_serial::SerialPortBuilderExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {

    let mut port = String::from("");

    let ports = tokio_serial::available_ports().unwrap();
    for p in ports {

        port = String::from("com1");

        match p.port_type {
            tokio_serial::SerialPortType::UsbPort(info) => {
                println!("{}, {:?}", p.port_name, info);
                port = p.port_name;
            },
            _ => println!("{}, unknown type", p.port_name),
        }

    }

    println!("port is {}", port);


    let slave = tokio_modbus::slave::Slave(0x3);
    let com = tokio_serial::new(port,9600)
        .timeout(std::time::Duration::from_millis(70))
        .data_bits(tokio_serial::DataBits::Eight)
        .stop_bits(tokio_serial::StopBits::One)
        .parity(tokio_serial::Parity::None)
        .open_native_async();  // tokio_serial::SerialPortBuilderExt

    // let com = tokio_serial::SerialStream::open(&builder).unwrap();

    // only open local serial_port
    let ctx = tokio_modbus::prelude::rtu::connect_slave(com.unwrap(), slave).await;

    let mut ctx = match ctx {
        Ok(c) => c,
        Err(e) => { println!("err is {}", e); return Ok(())},
    };

    println!("rtu ctx ok, {:?}", ctx);

    let now = std::time::Instant::now();

    // let mut timeend = tokio::time::sleep(std::time::Duration::from_millis(100));
    tokio::select! {
        result = &ctx.read_holding_registers(3,12) => match result {
            Ok(v) => println!("Reading holding {:?}", v),
            Err(_) => println!("reading err"),
        },
        _ = tokio::time::sleep(std::time::Duration::from_millis(100)) => println!("reading timeout 100 ms"),
    }

    println!("elapsed {} millis", now.elapsed().as_millis());
    Ok(())
}

复制代码

相关推荐

  1. Rust字符串处理及相关方法详解

    2023-12-27 10:08:02       23 阅读
  2. RustResult处理方式

    2023-12-27 10:08:02       33 阅读
  3. Rust单元测试

    2023-12-27 10:08:02       11 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-27 10:08:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-27 10:08:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-27 10:08:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-27 10:08:02       18 阅读

热门阅读

  1. Spring Boot学习:Redis发布订阅

    2023-12-27 10:08:02       33 阅读
  2. SQL使用从入门到优化:目录

    2023-12-27 10:08:02       39 阅读
  3. Flink on K8S集群搭建及StreamPark平台安装

    2023-12-27 10:08:02       39 阅读
  4. Django、Python版本升级问题大汇总

    2023-12-27 10:08:02       40 阅读
  5. vue前端的ref()用法

    2023-12-27 10:08:02       36 阅读
  6. iOS获取手机型号(包含iOS15系列)

    2023-12-27 10:08:02       37 阅读
  7. 排序实训问答

    2023-12-27 10:08:02       36 阅读
  8. 博客搬家公告

    2023-12-27 10:08:02       42 阅读
  9. centos卸载jenkins

    2023-12-27 10:08:02       40 阅读
  10. python读取xlsx格式的excel

    2023-12-27 10:08:02       38 阅读