面试题答案
一键面试use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
// 使用Arc来实现跨线程的数据共享
let shared_data = Arc::new(Mutex::new(0));
// 创建第一个线程,用于修改共享数据
let thread1 = thread::spawn({
let shared_data = Arc::clone(&shared_data);
move || {
let mut data = shared_data.lock().unwrap();
*data += 1;
}
});
// 创建第二个线程,用于读取共享数据
let thread2 = thread::spawn({
let shared_data = Arc::clone(&shared_data);
move || {
let data = shared_data.lock().unwrap();
println!("Read data: {}", *data);
}
});
// 等待线程结束
thread1.join().unwrap();
thread2.join().unwrap();
}
Mutex
结构体的主要方法及其作用:
lock
:- 作用:尝试获取锁。如果锁可用,则返回一个
MutexGuard
智能指针,它实现了Deref
和Drop
trait,当MutexGuard
离开作用域时,会自动释放锁。如果锁当前被其他线程持有,调用线程会被阻塞,直到锁可用。 - 示例:
let mut data = shared_data.lock().unwrap();
- 作用:尝试获取锁。如果锁可用,则返回一个
try_lock
:- 作用:尝试获取锁,但不会阻塞。如果锁可用,返回一个
Result<MutexGuard, PoisonError<MutexGuard>>
,其中Ok
包含MutexGuard
,Err
表示获取锁失败(例如锁被毒死,即持有锁的线程发生了恐慌)。 - 示例:
let result = shared_data.try_lock();
- 作用:尝试获取锁,但不会阻塞。如果锁可用,返回一个
into_inner
:- 作用:如果锁当前未被任何线程持有,将
Mutex
内部封装的数据取出,同时销毁Mutex
。 - 示例:
let data = shared_data.into_inner().unwrap();
- 作用:如果锁当前未被任何线程持有,将
poison
:- 作用:将
Mutex
标记为“毒死”状态。当持有锁的线程发生恐慌时,Mutex
会自动进入毒死状态,后续对锁的操作(除了try_lock
)都会返回PoisonError
。 - 示例:
shared_data.poison();
(通常不需要手动调用,恐慌时会自动处理)
- 作用:将