例
Arc と Mutex が実際にどのように動作するかを見てみましょう:
// 著作権 2024 Google LLC // SPDX-License-Identifier: Apache-2.0 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()); }
解答例:
// 著作権 2024 Google LLC // SPDX-License-Identifier: Apache-2.0 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()); }
注目すべき点:
vはArcとMutexの両方でラップされています。これは、それぞれが扱う関心事が 直交しているためです。MutexをArcでラップするのは、スレッド間で可変状態を共有するための 一般的なパターンです。
v: Arc<_>は、新しく生成される各スレッド用に新しい参照を作るために クローンする必要があります。ラムダのシグネチャにmoveが追加されている点に注意してください。LockGuardのスコープを可能な限り狭めるために、ブロックが導入されています。