面试题答案
一键面试在 Rust 中,可以使用 Arc
(原子引用计数)和 Mutex
(互斥锁)来实现数据所有权的正确转移和借用,确保并发安全并避免数据竞争。以下是具体的代码示例及原理解释:
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
// 使用 Arc 和 Mutex 包装主线程中的数据
let data = Arc::new(Mutex::new(42));
// 创建子线程,并将数据的 Arc 克隆一份传递给子线程
let data_clone = data.clone();
let handle = thread::spawn(move || {
// 尝试获取 Mutex 的锁,如果成功,返回一个 MutexGuard,它实现了 Deref 可以像普通引用一样访问数据
let mut data = data_clone.lock().unwrap();
*data += 1;
println!("子线程修改后的数据: {}", data);
});
// 主线程继续执行
let mut data = data.lock().unwrap();
*data += 1;
println!("主线程修改后的数据: {}", data);
// 等待子线程结束
handle.join().unwrap();
}
原理解释
Arc
:Arc
用于在多个线程间共享数据,它通过原子引用计数确保数据在所有引用都被释放时才被销毁。这里使用Arc
包装Mutex
包裹的数据,使得主线程和子线程可以安全地共享这份数据。Mutex
:Mutex
提供了互斥访问机制,确保同一时间只有一个线程可以访问被保护的数据。lock
方法尝试获取锁,如果锁可用则返回一个MutexGuard
,这个MutexGuard
在其生命周期内持有锁,当MutexGuard
离开作用域时,锁会自动释放。- 数据所有权和借用:通过
Arc::clone
方法克隆Arc
指针,使得主线程和子线程各自持有一个指向相同数据的Arc
实例。闭包中使用move
关键字,确保data_clone
的所有权被转移到子线程中。同时,通过Mutex
的锁机制,保证在同一时间只有一个线程能访问和修改数据,从而避免数据竞争。