面试题答案
一键面试-
使用
Arc
和Mutex
:Arc
(原子引用计数)用于在多个线程间共享数据,它允许数据有多个所有者。Mutex
(互斥锁)用于保护数据,确保同一时间只有一个线程可以访问数据。
use std::sync::{Arc, Mutex}; use std::thread; struct SharedData { value: i32 } fn main() { let shared_data = Arc::new(Mutex::new(SharedData { value: 0 })); let mut handles = vec![]; for _ in 0..10 { let data = Arc::clone(&shared_data); let handle = thread::spawn(move || { let mut data = data.lock().unwrap(); data.value += 1; println!("Thread updated value: {}", data.value); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } }
-
解释:
- 首先,我们创建了一个
Arc<Mutex<SharedData>>
类型的shared_data
。Arc
允许SharedData
结构体在多个线程间共享,而Mutex
确保对SharedData
内部数据(即value
)的访问是线程安全的。 - 在每个线程中,我们通过
data.lock().unwrap()
获取对Mutex
保护的数据的可变引用。lock
方法会阻塞当前线程,直到获取到锁,从而确保同一时间只有一个线程可以访问SharedData
。 - 对
data.value
进行操作后,我们释放了锁,其他线程就可以获取锁并进行操作。 - 最后,我们通过
join
方法等待所有线程完成。
- 首先,我们创建了一个
-
使用
RwLock
(如果读操作频繁):RwLock
(读写锁)允许多个线程同时进行读操作,但只允许一个线程进行写操作。
use std::sync::{Arc, RwLock}; use std::thread; struct SharedData { value: i32 } fn main() { let shared_data = Arc::new(RwLock::new(SharedData { value: 0 })); let mut handles = vec![]; for _ in 0..5 { let data = Arc::clone(&shared_data); let handle = thread::spawn(move || { let data = data.read().unwrap(); println!("Thread read value: {}", data.value); }); handles.push(handle); } for _ in 0..3 { let data = Arc::clone(&shared_data); let handle = thread::spawn(move || { let mut data = data.write().unwrap(); data.value += 1; println!("Thread updated value: {}", data.value); }); handles.push(handle); } for handle in handles { handle.join().unwrap(); } }
-
解释:
- 这里我们使用
Arc<RwLock<SharedData>>
来管理共享数据。 - 对于读操作,我们通过
data.read().unwrap()
获取不可变引用,允许多个线程同时读取。 - 对于写操作,我们通过
data.write().unwrap()
获取可变引用,这会阻塞其他读操作和写操作,确保数据一致性。
- 这里我们使用