The following code deadlocks because the mutex is not unlocked after the last use of v
:
use std::sync::{Arc,Mutex};
fn main() {
let a = Arc::new(Mutex::new(3));
let mut v = a.lock().unwrap();
*v += 1;
println!("v is {v}");
// drop(v);
let b = Arc::clone(&a);
std::thread::spawn(move || {
let mut w = b.lock().unwrap();
*w += 1;
println!("w is {w}");
}).join().unwrap();
}
The fix is to uncomment the explicit drop(v)
. Why does compiler not automatically drop v
after its last use?
In contrast, the Rust compiler knows to correctly drop v
early in the following case:
fn main() {
let mut a = 3;
let v = &mut a;
*v += 1;
println!("v is {v}");
let w = &mut a;
*w += 1;
println!("w is {w}");
}
This behavior seems natural, I would expect the compiler to do the same above.