我想在并发程序中使用rustbox
库。
但是,rustbox::RustBox
没有实现Send
特性,因此我无法在线程之间共享对象。
extern crate rustbox;
use std::thread;
use std::sync::{ self, Arc, Mutex };
use std::default::Default;
fn main() {
let rustbox = match rustbox::RustBox::init(Default::default()) {
Ok(r) => r,
_ => panic!(""),
};
let count = Arc::new(Mutex::new(0usize));
let (tx, rx) = sync::mpsc::channel();
let count_clone = count.clone();
thread::scoped(move|| {
loop {
let _ = rx.recv().unwrap();
show(&rustbox, count_clone.lock().unwrap().clone());
}
});
loop {
if let Ok(_) = rustbox.poll_event(false) {
let mut i = count.lock().unwrap();
*i += 1;
show(&rustbox, i.clone());
} else {
tx.send(()).unwrap();
}
}
}
fn show(rustbox: &rustbox::RustBox, count: usize) {
use rustbox::Color;
rustbox.print(1, 1, rustbox::RB_BOLD, Color::Default, Color::Default, &format!("{}", count));
}
tx.send(()).unwrap();
将在其他线程中发生。编译器错误消息是:
src/main.rs:16:5: 16:19 error: the trait `core::marker::Send` is not implemented for the type `rustbox::RustBox` [E0277]
src/main.rs:16 thread::scoped(move|| {
^~~~~~~~~~~~~~
src/main.rs:16:5: 16:19 note: `rustbox::RustBox` cannot be sent between threads safely
src/main.rs:16 thread::scoped(move|| {
^~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `sof`.
最佳答案
由于您使用的是scoped
线程,这些线程一定会在rustbox
之前消失,因此,如果它是Sync
,则可以简单地共享对rustbox的引用。
fn main() {
let rustbox = match rustbox::RustBox::init(Default::default()) {
Ok(r) => r,
_ => panic!(""),
};
let rustbox = &rustbox;
let count = Arc::new(Mutex::new(0usize));
let (tx, rx) = sync::mpsc::channel();
let count_clone = count.clone();
thread::scoped(move|| {
loop {
let _ = rx.recv().unwrap();
show(rustbox, count_clone.lock().unwrap().clone());
}
});
loop {
if let Ok(_) = rustbox.poll_event(false) {
let mut i = count.lock().unwrap();
*i += 1;
show(rustbox, i.clone());
} else {
tx.send(()).unwrap();
}
}
}
如果不是
Sync
,则只需将其包装在Mutex
中并共享对此的引用。注意:这仅是可能的,因为您使用的是
thread::scoped
,如果您使用的是thread::spawned
,那么Send
将是必需的。