如何在线程之间共享非发送对象?

时间:2015-04-14 13:59:40

标签: multithreading concurrency rust

我想在我的并发程序中使用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`.

1 个答案:

答案 0 :(得分:0)

由于您使用scoped线程,保证在 rustbox之前死亡,您可以简单地共享对rustbox 的引用,如果它是{{1 }}

Sync

如果不是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将是强制性的。