在两个线程之间共享一个大的只读结构的最佳方法是什么?

时间:2016-08-02 23:55:10

标签: multithreading rust shared-memory

一个线程计算一些占用大约1GB RAM的数据,而另一个线程只读取这些数据。实现这个的最佳方法是什么?

use std::thread;
use std::time::Duration;

fn main() {

    let mut shared: i32 = 0; // will be changed to big structure

    thread::spawn(move || {
        loop {
            shared += 1;
            println!("write shared {}", shared);
            thread::sleep(Duration::from_secs(2));
        }
    });

    thread::spawn(move || {
        loop {
            thread::sleep(Duration::from_secs(1));
            println!("read shared = ???"); // <---------------- ????
        }
    });

    thread::sleep(Duration::from_secs(4));
    println!("main");
}

您可以运行this code online(play.rust-lang.org)

1 个答案:

答案 0 :(得分:3)

代码和你的陈述并没有真正有意义。例如,在第一个线程有机会启动之前,没有任何东西阻止第二个线程完成。是的,我看到了睡眠,但睡觉并不是一个可行的并发解决方案

对于提出的问题,我会使用channel。这允许一个线程产生一个值,然后将该值的所有权转移到另一个线程:

use std::thread;
use std::sync::mpsc;

fn main() {
    let (tx, rx) = mpsc::channel();

    let a = thread::spawn(move || {
        let large_value = 1;
        println!("write large_value {}", large_value);
        tx.send(large_value).expect("Unable to send");
    });

    let b = thread::spawn(move || {
        let large_value = rx.recv().expect("Unable to receive");
        println!("read shared = {}", large_value);
    });

    a.join().expect("Unable to join a");
    b.join().expect("Unable to join b");

    println!("main");
}

对于显示的代码,除了MutexRwLock之外,实际上没有其他选项。这允许一个线程突变共享值一段时间,然后另一个线程可能会读取它一段时间(受操作系统调度程序的变幻莫测):

use std::thread;
use std::time::Duration;
use std::sync::{Arc, Mutex};

fn main() {
    let shared = Arc::new(Mutex::new(0));

    let shared_1 = shared.clone();
    thread::spawn(move || {
        loop {
            let mut shared = shared_1.lock().expect("Unable to lock");
            *shared += 1;
            println!("write large_value {}", *shared);
        }
    });

    thread::spawn(move || {
        loop {
            let shared = shared.lock().expect("Unable to lock");
            println!("read shared = {}", *shared);
        }
    });

    thread::sleep(Duration::from_secs(1));
    println!("main");
}

这一切对Rust来说都不是特别独特;在Go和Clojure中频道很受欢迎,互联网已存在很长时间。我建议你查看互联网上众多初学者指南中的任何一篇,了解多线程及其中的危险。