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

How to share non-Send objects between threads?

我想在我的并发程序中使用 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 死亡,您可以简单地共享对 rustbox 的引用 如果是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,则 Send 将是强制性的。