面试题答案
一键面试-
Arc
和RwLock
的作用:Arc
(原子引用计数)用于在多个线程间共享数据,它允许数据在堆上分配,并在多个线程间安全地引用。RwLock
(读写锁)用于保护共享数据,允许多个读操作并发执行,但写操作必须独占访问,以避免数据竞争。
-
代码示例:
use std::sync::{Arc, RwLock};
use std::thread;
fn main() {
// 创建一个Arc<RwLock<T>>来保护共享数据
let data = Arc::new(RwLock::new(0));
// 存储线程句柄的向量
let mut handles = vec![];
// 创建多个读线程
for _ in 0..10 {
let data_clone = data.clone();
let handle = thread::spawn(move || {
let value = data_clone.read().unwrap();
println!("Read value: {}", value);
});
handles.push(handle);
}
// 创建写线程
let data_clone = data.clone();
let write_handle = thread::spawn(move || {
let mut value = data_clone.write().unwrap();
*value += 1;
println!("Write value: {}", value);
});
handles.push(write_handle);
// 等待所有线程完成
for handle in handles {
handle.join().unwrap();
}
}
- 代码解释:
let data = Arc::new(RwLock::new(0));
:创建一个Arc<RwLock<i32>>
实例,初始值为0。Arc
允许在多个线程间共享RwLock
,RwLock
用于保护内部的i32
数据。- 读线程部分:
let data_clone = data.clone();
:为每个读线程克隆Arc
,这样每个线程都有自己对共享数据的引用。let value = data_clone.read().unwrap();
:调用read
方法获取读锁,这允许其他读操作并发执行。unwrap
用于在获取锁失败时(在这个简单示例中不会发生)使程序崩溃并打印错误信息。
- 写线程部分:
let data_clone = data.clone();
:同样克隆Arc
给写线程。let mut value = data_clone.write().unwrap();
:调用write
方法获取写锁,这会独占访问共享数据,直到写操作完成。*value += 1;
:修改共享数据。
for handle in handles { handle.join().unwrap(); }
:等待所有线程完成,确保所有读和写操作都执行完毕。