面试题答案
一键面试常见编程场景及锁中毒原因
- 线程恐慌(Panic)
- 场景:当持有锁的线程在临界区内发生恐慌(panic)时,就可能出现锁中毒。例如,在下面这段代码中:
use std::sync::{Arc, Mutex};
fn main() {
let data = Arc::new(Mutex::new(0));
let data_clone = data.clone();
let handle = std::thread::spawn(move || {
let mut num = data_clone.lock().unwrap();
*num = 1;
panic!("Oops!");
});
handle.join().unwrap();
let num = data.lock().unwrap();
println!("{}", *num);
}
- **原因**:Rust中的Mutex遵循RAII(Resource Acquisition Is Initialization)原则,锁在离开作用域时会自动释放。但是当线程恐慌时,线程不会正常地离开作用域,导致锁没有被正确释放。后续其他线程尝试获取该锁时,就会发现锁处于一种无法正常获取的“中毒”状态。
2. 异常退出 - 场景:持有锁的线程由于操作系统层面的原因(如进程被强制杀死、系统崩溃等异常情况)非正常退出。虽然在正常的Rust程序逻辑中较难模拟这种场景,但在实际运行环境中可能发生。 - 原因:类似于线程恐慌,线程没有机会正常释放锁。操作系统突然终止线程,使得锁资源处于不一致状态,其他线程尝试获取锁时就会遭遇锁中毒。