代码之家  ›  专栏  ›  技术社区  ›  ritiek

如何为RustBox实现同步?

  •  1
  • ritiek  · 技术社区  · 9 年前

    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 对于 生锈的箱子 键入以使上述代码可以工作?

    1 回复  |  直到 9 年前
        1
  •  1
  •   ritiek    9 年前

    RustBox 不执行 Send ,因此没有(安全的)方法在线程之间共享它(似乎您已经找到了尚未合并的pull请求) https://github.com/gchp/rustbox/pull/65 这将支持 邮寄 ).

    生锈的箱子 在一个 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 函数,您必须将 生锈的箱子 :

    let rustbox = Arc::new(Mutex::new(rustbox));
    

    和 lock() 每次你使用它。

    确保锁不要放得太久;使用辅助变量可能有助于使其更明确,例如:

    let pe = rustbox.lock().unwrap().poll_event(false);
    match pe {
    // ...
    }