- 代码实现:
use std::sync::atomic::{AtomicU32, Ordering};
use std::thread;
fn main() {
let counter = AtomicU32::new(0);
let mut handles = vec![];
for _ in 0..10 {
let counter_clone = counter.clone();
let handle = thread::spawn(move || {
counter_clone.fetch_add(1, Ordering::SeqCst);
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Final counter value: {}", counter.load(Ordering::SeqCst));
}
- 原子操作保证数据一致性的原因:
- 在多线程环境下,多个线程可能同时访问和修改共享数据。如果不使用原子操作,就会出现竞态条件(race condition)。例如,一个线程读取共享整数的值,在另一个线程修改该值后,第一个线程再基于旧值进行修改,这就导致数据不一致。
- 原子操作通过硬件或操作系统提供的特殊指令来实现。在Rust中,
std::sync::atomic
模块提供的原子类型(如AtomicU32
)的操作(如fetch_add
)是不可分割的,即不会被其他线程中断。这样,无论有多少线程同时尝试对共享整数进行递增操作,每个操作都是原子的,从而保证了多线程环境下的数据一致性。Ordering
参数(如Ordering::SeqCst
)用于指定内存顺序,进一步控制对原子操作的同步和可见性规则,确保在不同线程之间的操作按预期顺序发生。