线程安全思路
- 使用
Arc
: Arc
(原子引用计数)用于在多个线程间共享数据,它提供了引用计数功能,确保数据在所有引用被释放时才会被销毁。由于Arc
是线程安全的,所以适合在多线程环境下使用。
- 使用
Mutex
: Mutex
(互斥锁)用于保护共享数据,确保在同一时间只有一个线程可以访问数据。线程在访问共享数据前需要先获取Mutex
的锁,访问结束后释放锁。
代码实现
use std::sync::{Arc, Mutex};
use std::thread;
// 定义共享数据结构
struct SharedData {
value: i32,
}
fn main() {
// 创建Arc<Mutex<SharedData>>实例
let shared_data = Arc::new(Mutex::new(SharedData { value: 0 }));
let mut handles = vec![];
// 创建3个读线程
for _ in 0..3 {
let data = Arc::clone(&shared_data);
let handle = thread::spawn(move || {
let data = data.lock().unwrap();
println!("Read value: {}", data.value);
});
handles.push(handle);
}
// 创建2个写线程
for _ in 0..2 {
let data = Arc::clone(&shared_data);
let handle = thread::spawn(move || {
let mut data = data.lock().unwrap();
data.value += 1;
println!("Write value: {}", data.value);
});
handles.push(handle);
}
// 等待所有线程结束
for handle in handles {
handle.join().unwrap();
}
}
代码解释
- 定义
SharedData
: 定义了包含可变状态value
的共享数据结构。
- 创建
Arc<Mutex<SharedData>>
: 使用Arc
和Mutex
来包装SharedData
,使它可以在多线程间安全共享并保护其内部数据。
- 创建读线程: 克隆
Arc
并传递给新线程,在新线程中通过lock
方法获取锁,从而安全地读取SharedData
中的数据。
- 创建写线程: 同样克隆
Arc
传递给新线程,获取锁后对SharedData
中的数据进行修改,由于获取了锁,不会出现数据竞争问题。
- 等待线程结束: 使用
join
方法等待所有线程执行完毕,确保程序不会在所有线程结束前退出。