如何在Rust的多线程中使用串行端口?

时间:2018-11-23 03:27:33

标签: rust serial-port borrow-checker

我正在尝试读写Linux上的串行端口以与微控制器通信,而我正试图在Rust中进行通信。

用C ++或Python开发时,我通常的模式是有两个线程:一个线程周期性地通过串行发送请求,另一个线程从缓冲区中读取字节并进行处理。

在Rust中,使用串行包装箱时我遇到了借阅检查器的麻烦。这对我来说是有道理的,但是我不确定在Rust中异步通信接口的设计是什么样的。这是我的来源的片段:

let mut port = serial::open(&device_path.as_os_str()).unwrap();
let request_temperature: Vec<u8> = vec![0xAA];

thread::spawn(|| {
    let mut buffer: Vec<u8> = Vec::new();
    loop {
        let _bytes_read = port.read(&mut buffer);
        // process data
        thread::sleep(Duration::from_millis(100));
    }
});

loop {
    port.write(&request_temperature);
    thread::sleep(Duration::from_millis(1000));
}

当在Rust中有两个线程持有可变资源时,如何模拟此功能?我知道,由于此特定示例可以在单个线程中完成,但是我正在考虑最终使用更大的程序,最终将是多个线程。

1 个答案:

答案 0 :(得分:2)

您可以将端口包装在ArcMutex中,然后可以编写如下内容:

use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;

struct Port;
impl Port {
    pub fn read(&mut self, _v: &mut Vec<u8>) {
        println!("READING...");
    }
    pub fn write(&mut self, _v: &Vec<u8>) {
        println!("WRITING...");
    }
}

pub fn main() {
    let mut port = Arc::new(Mutex::new(Port));
    let p2 = port.clone();

    let handle = thread::spawn(move || {
        let mut buffer: Vec<u8> = Vec::new();
        for j in 0..100 {
            let _bytes_read = p2.lock().unwrap().read(&mut buffer);
            thread::sleep(Duration::from_millis(10));
        }
    });

    let request_temperature: Vec<u8> = vec![0xAA];
    for i in 0..10 {
        port.lock().unwrap().write(&request_temperature);
        thread::sleep(Duration::from_millis(100));
    }

    handle.join();
}

为了使它可以在测试机上运行,​​我用存根类替换了串行端口,减少了睡眠,并用一些有限循环替换了无限循环。

虽然可行,但实际上您可能需要在某个阶段在线程之间进行适当的通信,这时您需要查看std::sync::mpsc::channel