闽公网安备 35020302035485号
use std::sync::{Arc, Mutex};
fn main() {
let shared_data = Arc::new(Mutex::new(vec![1, 2, 3]));
// 堆代码 duidaima.com
// 生成两个访问共享数据的线程
for i in 0..2 {
let shared_data = Arc::clone(&shared_data);
std::thread::spawn(move || {
let mut data = shared_data.lock().unwrap();
data.push(i);
});
}
}
在本例中,我们首先使用std::sync模块中的Mutex类型创建一个名为shared_data的互斥锁,这个互斥锁保护对整数向量的访问,它最初被设置为包含值[1,2,3]。这段代码的问题在于,如果一个线程在持有锁时发生了恐慌,它可能会使互斥锁处于不一致的状态,从而使另一个线程无法获得锁。这就是所谓的互斥锁中毒,它会导致等待该锁的其他线程无限期地阻塞。
use std::sync::{Arc, Mutex, MutexGuard};
use std::thread;
fn main() {
let shared_data = Arc::new(Mutex::new(vec![1, 2, 3]));
let mut handles = Vec::new();
// 生成两个访问共享数据的线程
for i in 0..2 {
let shared_data = shared_data.clone(); // Clone the Arc to move into the thread
let handle = thread::spawn(move || {
let mut data: MutexGuard<Vec<i32>> = match shared_data.lock() {
Ok(guard) => guard,
Err(poisoned) => {
// 处理互斥锁中毒
let guard = poisoned.into_inner();
println!("Thread {} recovered from mutex poisoning: {:?}", i, *guard);
guard
}
};
// Use the data
println!("Thread {}: {:?}", i, *data);
data.push(i);
});
handles.push(handle);
}
// Wait for the threads to finish
for handle in handles {
handle.join().unwrap();
}
}
在上面的代码中,我们首先使用Arc和Mutex创建了一个共享数据结构。然后我们生成两个线程来访问共享数据。当线程尝试使用lock()方法获取共享资源上的锁时,它返回Result类型。如果锁没有中毒,结果为Ok,线程可以安全地使用数据。如果锁已中毒,则Result是带有中毒变体的Err。