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]);