我是Rust的新手。我正在努力从线程中的RustBox
type包中传递rustbox。
我想按下 q 键并让它在(1,1)处显示+
符号2秒,而我按 w 键那些2秒在(1,2)处显示另一个+
符号。
我为同一个逻辑编写了一些代码:
extern crate rustbox;
use std::thread;
use std::time::Duration;
use rustbox::{Color, RustBox};
use rustbox::Key;
fn mark_at(x: usize, y: usize, rustbox: &RustBox) {
rustbox.print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, "+");
thread::spawn(move || {
let delay = Duration::from_millis(2000);
thread::sleep(delay);
rustbox.print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, " ");
});
}
fn main() {
let rustbox = match RustBox::init(Default::default()) {
Result::Ok(v) => v,
Result::Err(e) => panic!("{}", e),
};
rustbox.print(1, 1, rustbox::RB_BOLD, Color::Black, Color::White, " ");
rustbox.print(1, 2, rustbox::RB_BOLD, Color::Black, Color::White, " ");
loop {
rustbox.present();
match rustbox.poll_event(false) {
Ok(rustbox::Event::KeyEvent(key)) => {
match key {
Key::Char('q') => {
mark_at(1, 1, &rustbox);
}
Key::Char('w') => {
mark_at(1, 2, &rustbox);
}
Key::Esc => { break; }
_ => { }
}
},
Err(e) => panic!("{}", e),
_ => { }
}
}
}
它给了我:
error[E0277]: the trait bound `*mut (): std::marker::Sync` is not satisfied in `rustbox::RustBox`
--> src/main.rs:12:5
|
12 | thread::spawn(move || {
| ^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
|
= help: within `rustbox::RustBox`, the trait `std::marker::Sync` is not implemented for `*mut ()`
= note: required because it appears within the type `std::marker::PhantomData<*mut ()>`
= note: required because it appears within the type `rustbox::RustBox`
= note: required because of the requirements on the impl of `std::marker::Send` for `&rustbox::RustBox`
= note: required because it appears within the type `[closure@src/main.rs:12:19: 16:6 rustbox:&rustbox::RustBox, x:usize, y:usize]`
= note: required by `std::thread::spawn`
error: aborting due to previous error
如何为Sync
类型实施RustBox
,以便上述代码可以使用?
答案 0 :(得分:1)
RustBox
没有实现Send
,所以没有(安全的)方法在线程之间共享它(似乎你已经找到了尚未合并的拉取请求https://github.com/gchp/rustbox/pull/65支持Send
)。
如果拉取请求合并,您可以将RustBox
包裹在Mutex
中,即Mutex<RustBox>
,并且可以在线程之间共享对它的引用。
但是你会遇到生命周期问题:你的rustbox
引用的活动时间不足以使用它生成一个新线程,因此你必须将它包装在Arc
中。
use std::sync::{Arc,Mutex};
fn mark_at(x: usize, y: usize, rustbox: &Arc<Mutex<RustBox>>) {
rustbox.lock().unwrap().print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, "+");
let rustbox = rustbox.clone(); // increment reference counter
thread::spawn(move || {
let delay = Duration::from_millis(2000);
thread::sleep(delay);
rustbox.lock().unwrap().print(x, y, rustbox::RB_BOLD, Color::Black, Color::White, " ");
});
}
在main
函数中,您必须包装rustbox
:
let rustbox = Arc::new(Mutex::new(rustbox));
每次使用时都会和lock()
。
确保不要将锁定时间过长;它可能有助于使用辅助变量使其更明确,例如:
let pe = rustbox.lock().unwrap().poll_event(false);
match pe {
// ...
}