Rust 多线程冻结与串口

问题描述 投票:0回答:1

我一直在开发一个 Rust 项目,通过串口与 Arduino 进行通信。 我发现了一些可以解决问题的货物依赖项。 但我测试过的少数几个,他们也有同样的问题:

我想要生成一个线程,以便可以阻止 Arduino 在任何给定时刻发送的任何传入数据。使用另一个线程从用户获取输入(例如从控制台输入)并将其发送到 Arduino,从而有 2 个线程同时运行。 但是随着该线程的运行,当线程等待来自 Arduino 的数据时,一旦我给出输入,应该写入 Arduino 的线程就会冻结在该方法上。

这里是使用 serialport 板条箱的示例代码:

use std::{
    io::{stdin, stdout, Read, Write},
    thread,
};

fn main() {
    let mut port = serialport::new("COM5", 9600).open().unwrap();
    let r_port = port.try_clone().unwrap();

    thread::spawn(move || {
        for rb in r_port.bytes() {
            // I've used all the read methods in their respective matter, but the write method still gets stuck no matter what.
            match rb {
                Ok(byte) => {
                    print!("{}", byte as char);
                    stdout().flush().unwrap();
                }
                Err(e) => {
                    eprintln!("{e}");
                }
            }
        }
    });

    loop {
        let mut input = String::new();
        stdin().read_line(&mut input).unwrap();
        port.write(input.as_bytes()).unwrap(); // thread gets stuck here
    }
}

是的,我确保通讯号正确且波特率一致。 非常感谢任何帮助!

multithreading rust serial-port
1个回答
0
投票

我会使用

Arc<Mutex>
来共享对
serialport
的访问。这可能不是最高效的方法,也不是最好的方法,但我想这是最省力的方法 - 只是开始。

(最好的方法可能是使用一个通道进行读取,一个通道进行写入,并且可能使用 Tokio 的异步方法)。

use std::{
    io::{stdin, stdout, Read, Write},
    thread,
};
use std::sync::{Arc, Mutex};

fn main() {
    let mut port = Arc::new(Mutex::new(serialport::new("COM5", 9600).open().unwrap()));
    let mut r_port = port.clone();  // create a new atomic ref-counted pointer to port

    thread::spawn(move || {
        loop {
            let p = r_port.bytes().lock();  // get access to the Mutexed port
            let num_bytes_to_read = r_port.bytes_to_read();
            if num_bytes_to_read > 0 {
                for rb in r_port.bytes() {
                    match rb {
                        Ok(byte) => {
                            print!("{}", byte as char);
                            stdout().flush().unwrap();
                        }
                        Err(e) => {
                            eprintln!("{e}");
                        }
                    }
                }
            } else {
                drop(p); // release lock
                time.sleep(Duration::from_msecs(100));  // make port available for writing for 100ms
            }
        }
    });

    loop {
        let mut input = String::new();
        stdin().read_line(&mut input).unwrap();
        let mut p = port.lock();
        p.write(input.as_bytes()).unwrap(); // thread gets stuck here
    }
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.