示例
让我们看看 Arc
和 Mutex
的实际效果:
use std::thread; // use std::sync::{Arc, Mutex}; fn main() { let v = vec![10, 20, 30]; let mut handles = Vec::new(); for i in 0..5 { handles.push(thread::spawn(|| { v.push(10 * i); println!("v: {v:?}"); })); } handles.into_iter().for_each(|h| h.join().unwrap()); }
This slide should take about 8 minutes.
可能有用的解决方案:
use std::sync::{Arc, Mutex}; use std::thread; fn main() { let v = Arc::new(Mutex::new(vec![10, 20, 30])); let mut handles = Vec::new(); for i in 0..5 { let v = Arc::clone(&v); handles.push(thread::spawn(move || { let mut v = v.lock().unwrap(); v.push(10 * i); println!("v: {v:?}"); })); } handles.into_iter().for_each(|h| h.join().unwrap()); }
值得注意的部分:
Arc
和Mutex
中都封装了v
,因为它们的关注点是正交的。- 将
Mutex
封装在Arc
中是一种在线程之间共享可变状态的常见模式。
- 将
v: Arc<_>
needs to be cloned to make a new reference for each new spawned thread. Notemove
was added to the lambda signature.- 我们引入了块,以尽可能缩小
LockGuard
的作用域。