由于在最后一次使用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();
}
修复方法是取消注解显式drop(v)
。为什么编译器在最后一次使用v
后不自动删除它?
相反,Rust编译器知道在以下情况下尽早正确删除v
:
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}");
}
这种行为看起来很自然,我希望编译器也能做到这一点。
1条答案
按热度按时间2wnc66cl1#
值会在作用域结束时被删除,而不是在最后一次使用之后。可能会让你感到困惑的是,borrow checker 知道 references 在最后一次使用之后是无关紧要的,因此出于强制Rust的引用保证的目的,会考虑它们的生存期。
从技术上讲,第二个示例中的
v
也是在作用域结束后才删除的,但是没有引用的删除逻辑。