面试题答案
一键面试锁中毒产生原因
在Rust并发编程中,当一个线程持有锁时发生了恐慌(panic),而这个锁没有正确释放,就会导致锁中毒。其他尝试获取该锁的线程会收到一个错误,表明锁已经中毒,无法正常获取。这是因为Rust的设计理念是保证内存安全和线程安全,一旦发生panic,需要清理相关资源以避免未定义行为。
处理方式及代码示例
一种基础的处理方式是在获取锁后,使用unwrap_or_else
方法来处理锁中毒错误。以下是示例代码:
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let data = Arc::new(Mutex::new(0));
let data_clone = data.clone();
let handle = thread::spawn(move || {
let mut num = data_clone.lock().unwrap();
// 模拟一个会发生panic的操作
if *num == 0 {
panic!("Something went wrong");
}
*num += 1;
});
match handle.join() {
Ok(_) => (),
Err(_) => (),
}
// 处理锁中毒
let result = data.lock().unwrap_or_else(|e| {
if e.is_poisoned() {
e.into_inner().unwrap()
} else {
panic!("Unexpected error: {:?}", e);
}
});
println!("Data after handling poison: {}", result);
}
在上述代码中,子线程获取锁并在特定条件下发生panic,导致锁中毒。主线程使用unwrap_or_else
方法来处理锁中毒错误,若锁中毒则获取锁内部的数据。