我正在尝试编写一个简单的库,它有一个后台工作线程,在调用库函数时处理命令。
我通常在C中执行它的方式是有一个全局信号量句柄,工作者可以阻止它。函数在发送命令后会给出信号量,此时工作人员会解锁等等......还有其他方法,但这只是一个例子。
关于如何用Rust实现类似的东西我有一些问题。
init()
时会创建线程,但是当init()
返回时会退出,如何防止这种情况?rx
从不同的功能访问tx
?例如send_cmd_a()
,send_cmd_b()
到同一个线程我想要完成的伪代码:
static (tx, rx) = mpsc::channel(); //how to do something like this?
fn init() {
thread::spawn(|| {
loop {
let cmd = rx.recv().unwrap(); //blocks till there is data
//process data....
if cmd == "exit" {
return;
}
}
});
}
fn send_cmd_a() {
//Do a bunch of other stuff...
tx.send("cmd_a").unwrap();
}
fn exit() {
tx.send("exit").unwrap();
}
我是否必须创建一个封装所有这些的大对象,从而拥有同步机制? (仍然不回答问题#1)
在Rust中做这样的事情的首选方式是什么?
我想我想出了一种方法来实现我想要的Rust,而不需要使用全局变量。
struct Device {
sender: Sender<u8>, //other stuff
}
trait New {
fn new() -> Self;
}
trait SendCommand {
fn send_command(&self, u8);
}
impl New for Device {
fn new() -> Device {
let (tx, rx) = channel();
let device = Device { sender: tx };
thread::spawn(move || {
loop {
let cmd = rx.recv().unwrap();
println!("Command: {}", cmd); //process commands here
}
});
return device;
}
}
impl SendCommand for Device {
fn send_command(&self, cmd: u8) {
self.sender.send(cmd).unwrap();
}
}
fn main() {
let dev = Device::new(); //create the device
for i in 0..10 {
dev.send_command(i); //send commands
sleep(Duration::from_millis(50));
}
loop {}
}