こういうコードを書くと当然deadlockする。
use std::sync::{Mutex, Arc}; use std::thread; fn main() { let mut lock = Arc::new(Mutex::new(false)); let mut cloned_lock = lock.clone(); let th = thread::spawn(move|| { loop { let mut quit = cloned_lock.lock().unwrap(); if *quit { break; } } }); let mut quit = lock.lock().unwrap(); *quit = true; th.join(); }
ロックの開放タイミングをいいかんじにするとちゃんと終了する。
use std::sync::{Mutex, Arc}; use std::thread; fn main() { let mut lock = Arc::new(Mutex::new(false)); let mut cloned_lock = lock.clone(); let th = thread::spawn(move|| { loop { let mut quit = cloned_lock.lock().unwrap(); if *quit { break; } } }); { let mut quit = lock.lock().unwrap(); *quit = true; } th.join(); }
さらに以下のように書いても正常に終了する。 おそらく変数スコープのところで獲得・開放してくれているのだろう。
use std::sync::{Mutex, Arc}; use std::thread; fn main() { let mut lock = Arc::new(Mutex::new(false)); let mut cloned_lock = lock.clone(); let th = thread::spawn(move|| { loop { let mut quit = cloned_lock.lock().unwrap(); if *quit { break; } } }); *lock.lock().unwrap() = true; th.join(); }
Rustいいなあ。