面试题答案
一键面试- 设计思路:
- 使用
thread::spawn
和catch_unwind
:在创建线程时,使用std::thread::spawn
来生成新线程,并在每个线程内部使用std::panic::catch_unwind
来捕获可能发生的panic
。这样,即使某个线程发生panic
,也不会导致整个程序崩溃。 - 共享状态管理:对于结构体的共享状态,使用合适的并发原语如
Mutex
或Arc
+Mutex
来保护,确保不同线程对结构体的访问是线程安全的。当捕获到panic
时,可以通过一些方式记录这个错误,比如将错误信息存入共享状态的结构体中,其他线程可以根据这个错误信息来决定后续的操作,例如优雅地退出或者继续执行关键部分的代码。
- 使用
- 关键代码片段:
use std::sync::{Arc, Mutex};
use std::thread;
use std::panic;
// 定义共享结构体
struct SharedData {
value: i32,
error: Option<String>,
}
fn main() {
let shared_data = Arc::new(Mutex::new(SharedData {
value: 0,
error: None,
}));
let mut handles = vec![];
for _ in 0..3 {
let shared_data_clone = shared_data.clone();
let handle = thread::spawn(move || {
let result = panic::catch_unwind(|| {
// 模拟可能发生panic的操作
let mut data = shared_data_clone.lock().unwrap();
data.value += 1;
if data.value == 2 {
panic!("Oops, something went wrong!");
}
});
if let Err(e) = result {
let mut data = shared_data_clone.lock().unwrap();
data.error = Some(format!("Thread panicked: {:?}", e));
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let data = shared_data.lock().unwrap();
if let Some(ref error) = data.error {
println!("Error occurred: {}", error);
} else {
println!("All threads completed successfully. Value: {}", data.value);
}
}
在上述代码中:
SharedData
结构体用于存储共享数据和可能发生的错误信息。- 在每个线程中,使用
panic::catch_unwind
捕获可能的panic
,如果捕获到panic
,则将错误信息记录到共享结构体的error
字段中。 - 主线程等待所有线程完成后,检查共享结构体中的
error
字段,根据情况输出错误信息或成功信息。