Mutex<T>は、共通リソースが複数のスレッド間で競合などが起きないようにしてくれます。::lockを実行することでMutexGuard<T>を取得できます。Tは安全に触りたい値のことで、MutextGuardがDerefを持ってることから楽に触る事ができます。
すべてのスレッドの処理が終わった後、再度Tを取得したい場合はメインスレッドで再度::lockし、MutexGuardに変換してから取得できます。
use std::sync::{Arc, Mutex};
use std::thread;
let values: Arc>> = Arc::new(Mutex::new(Vec::new()));
for i in 0..10 {
let values = values.clone();
thread::spawn(move || {
let mut lock = values.lock().unwrap();
lock.push(i);
})
.join()
.unwrap();
}
let values = values.lock().unwrap();
assert_eq!(*values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); あるスレッドのMutexGuardがスコープを抜けるまで他スレッドでは値を取得できない状態が続きます。なので以下のように書き換えると2つめの"foo"が出るまでに1秒の遅れが生まれます。
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
let values: Arc>> = Arc::new(Mutex::new(Vec::new()));
for i in 0..10 {
let values = values.clone();
thread::spawn(move || {
let mut lock = values.lock().unwrap();
println!("foo");
lock.push(i);
if i == 0 {
thread::sleep(Duration::from_secs(1));
}
})
.join()
.unwrap();
}
let values = values.lock().unwrap();
assert_eq!(*values, vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);