Open3
Mutex
- mutexとは
- 並行処理されるプロセス間において利用されるリソースを排他制御するための仕組み
- https://wa3.i-3-i.info/word13360.html
- サンプルコード
let mutex: Mutex<i32> = Mutex::new(0);
println!("mutex: {:?}", mutex);
let mut val: std::sync::MutexGuard<'_, i32> = mutex.lock().unwrap();
println!("mutex: {:?}", mutex);
*val = 10;
println!("val: {}", val);
drop(val);
mutex: Mutex { data: 0, poisoned: false, .. }
mutex: Mutex { data: <locked>, poisoned: false, .. }
val: 10
スコープを抜ける or drop を呼び出すと、ロックを解除できる
- ロックを取ると、mutex は解放されるまで待っている
- 待たない、サンプルコード
pub fn run() {
let counter = Arc::new(Mutex::new(0));
let handle1 = {
thread::spawn(move || {
// wait for 3 seconds
thread::sleep(std::time::Duration::from_secs(3));
println!("thread1 ends")
})
};
let handle2 = {
thread::spawn(move || {
// wait for 1 second
thread::sleep(std::time::Duration::from_secs(1));
println!("thread2 ends")
})
};
handle1.join().unwrap();
handle2.join().unwrap();
println!("finish all threads");
}
thread2 ends
thread1 ends
finish all threads
このコードでは、スレッドが二つ同時に走って、指定された秒数待ってから終了する
スレッド同士に特に関係はなく、独立して動いています
- まつサンプルコード
pub fn run() {
let counter = Arc::new(Mutex::new(0));
let counter1 = Arc::clone(&counter);
let handle1 = thread::spawn(move || {
println!("thread1 started");
let mut num = counter1.lock().unwrap();
println!("counter: {:?}", counter1);
println!("num: {:?}", num);
// wait for 3 seconds
thread::sleep(std::time::Duration::from_secs(3));
*num += 1;
});
let counter2 = Arc::clone(&counter);
let handle2 = thread::spawn(move || {
println!("thread2 started");
let mut num = counter2.lock().unwrap();
println!("counter: {:?}", counter2);
println!("num: {:?}", num);
*num += 1;
});
handle1.join().unwrap();
handle2.join().unwrap();
println!("Result: {}", *counter.lock().unwrap());
}
thread1 started
counter: Mutex { data: <locked>, poisoned: false, .. }
num: 0
thread2 started
--- 3秒後 ---
counter: Mutex { data: <locked>, poisoned: false, .. }
num: 1
Result: 2
thread2 のロックを取得する箇所で、thread1 でロックが解除されるのを待っている
- 3秒待つ前に解放する
pub fn run() {
let counter = Arc::new(Mutex::new(0));
let counter1 = Arc::clone(&counter);
let handle1 = thread::spawn(move || {
println!("thread1 started");
let mut num = counter1.lock().unwrap();
println!("counter: {:?}", counter1);
println!("num: {:?}", num);
*num += 1;
drop(num);
// wait for 3 seconds
thread::sleep(std::time::Duration::from_secs(3));
});
let counter2 = Arc::clone(&counter);
let handle2 = thread::spawn(move || {
println!("thread2 started");
let mut num = counter2.lock().unwrap();
println!("counter: {:?}", counter2);
println!("num: {:?}", num);
*num += 1;
});
handle1.join().unwrap();
handle2.join().unwrap();
println!("Result: {}", *counter.lock().unwrap());
}
thread1 started
counter: Mutex { data: <locked>, poisoned: false, .. }
num: 0
thread2 started
counter: Mutex { data: <locked>, poisoned: false, .. }
num: 1
--- 3秒後 ---
Result: 2
- デッドロック
- サンプルコード
fn run3() {
let counter = Mutex::new(0);
let lock1 = counter.lock().unwrap();
let lock2 = counter.lock().unwrap();
println!("lock: {:?}", lock1);
}
lock2 は lock1 がロックしたものを待っているが、ずっと解放されない