如何在 Rust 的多线程中使用串口?
How to Use Serial Port in Multiple Threads in Rust?
我正在尝试读取和写入 Linux 上的串行端口以与微控制器通信,我正在尝试在 Rust 中这样做。
我在 C++ 或 Python 中开发时的正常模式是有两个线程:一个通过串行周期性地发送请求,另一个从缓冲区读取字节并处理它们。
在 Rust 中,我 运行 在使用 serial crate 时遇到了借用检查器的麻烦。这对我来说很有意义,但我不确定在 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 中有两个线程占用可变资源的情况下模拟此功能?我知道,因为这个具体的例子可以在一个线程中完成,但我正在考虑一个最终更大的程序,这最终会成为多个线程。
您可以将您的端口包装在 Arc
and a Mutex
中,然后您可以这样写:
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();
}
因此这将 运行 在测试机器上,我用存根 class 替换了串口,减少了睡眠并用一些有限循环替换了无限循环。
虽然这可行,但您可能实际上希望在某个阶段线程之间进行适当的通信,此时您需要查看 std::sync::mpsc::channel
我正在尝试读取和写入 Linux 上的串行端口以与微控制器通信,我正在尝试在 Rust 中这样做。
我在 C++ 或 Python 中开发时的正常模式是有两个线程:一个通过串行周期性地发送请求,另一个从缓冲区读取字节并处理它们。
在 Rust 中,我 运行 在使用 serial crate 时遇到了借用检查器的麻烦。这对我来说很有意义,但我不确定在 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 中有两个线程占用可变资源的情况下模拟此功能?我知道,因为这个具体的例子可以在一个线程中完成,但我正在考虑一个最终更大的程序,这最终会成为多个线程。
您可以将您的端口包装在 Arc
and a Mutex
中,然后您可以这样写:
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();
}
因此这将 运行 在测试机器上,我用存根 class 替换了串口,减少了睡眠并用一些有限循环替换了无限循环。
虽然这可行,但您可能实际上希望在某个阶段线程之间进行适当的通信,此时您需要查看 std::sync::mpsc::channel