在两个线程之间共享大型只读结构的最佳方法是什么?
What is the best way to share a big read-only structure between two threads?
一个线程计算一些数据,大约需要 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)
代码和您的陈述并没有真正的意义。例如,没有什么可以阻止第二个线程在第一个线程有机会开始之前完成。是的,我看到了睡眠,但是 睡眠不是一个可行的并发解决方案。
对于所问的问题,我会使用 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");
}
对于所提供的代码,除了 Mutex
or a RwLock
之外真的没有其他选择。这允许一个线程暂时改变共享值,然后另一个线程可能会读取它一段时间(受 OS 调度器变化无常的影响):
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");
}
None 这是 Rust 特有的;通道在 Go 和 Clojure 中非常流行,互斥量已经存在了很长时间。我建议查看 Internet 上众多初学者指南中的任何一个以了解多线程及其中的危险。
一个线程计算一些数据,大约需要 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)
代码和您的陈述并没有真正的意义。例如,没有什么可以阻止第二个线程在第一个线程有机会开始之前完成。是的,我看到了睡眠,但是 睡眠不是一个可行的并发解决方案。
对于所问的问题,我会使用 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");
}
对于所提供的代码,除了 Mutex
or a RwLock
之外真的没有其他选择。这允许一个线程暂时改变共享值,然后另一个线程可能会读取它一段时间(受 OS 调度器变化无常的影响):
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");
}
None 这是 Rust 特有的;通道在 Go 和 Clojure 中非常流行,互斥量已经存在了很长时间。我建议查看 Internet 上众多初学者指南中的任何一个以了解多线程及其中的危险。