面试题答案
一键面试- 使用原子类型避免数据竞争:
- 在 Rust 中,
std::sync::atomic
模块提供了原子类型,如AtomicU32
等。原子类型保证对其值的操作是原子的,即在多线程环境下不会出现数据竞争。 - 当多个线程需要读取和更新进度数据(例如完成任务的百分比)时,可以使用
AtomicU32
来存储这个进度值。更新操作可以使用fetch_add
等原子方法,读取操作可以使用load
方法。这些方法都提供了内存顺序参数,用于控制内存访问的顺序,以确保线程安全。
- 在 Rust 中,
- 代码示例:
use std::sync::{Arc, atomic::{AtomicU32, Ordering}};
use std::thread;
fn main() {
let progress = Arc::new(AtomicU32::new(0));
let mut handles = vec![];
for _ in 0..10 {
let progress_clone = Arc::clone(&progress);
let handle = thread::spawn(move || {
for _ in 0..10 {
// 原子地增加进度
progress_clone.fetch_add(1, Ordering::SeqCst);
// 原子地读取进度
let current_progress = progress_clone.load(Ordering::SeqCst);
println!("Thread is at progress: {}%", current_progress);
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
let final_progress = progress.load(Ordering::SeqCst);
println!("Final progress: {}%", final_progress);
}
在上述代码中:
- 首先创建了一个
Arc<AtomicU32>
类型的progress
,Arc
用于在多个线程间共享数据,AtomicU32
确保对数据的原子操作。 - 在每个线程中,使用
fetch_add
原子地增加进度值,并使用load
原子地读取进度值并打印。 - 主线程等待所有子线程完成后,读取并打印最终的进度值。