面试题答案
一键面试设计思路
- 使用原子类型:Rust 的
std::sync::atomic
模块提供了原子类型,如AtomicUsize
,可以在多线程环境下进行无锁操作,避免锁竞争。 - 缓存一致性:原子操作通过硬件指令保证了内存可见性,确保所有线程看到的原子变量状态一致。
- 减少争用:为了进一步优化性能,可以采用无锁数据结构或者减少对共享资源的访问频率。例如,每个线程可以先在本地进行计数,然后定期将本地计数合并到共享的原子计数器上。
关键代码片段
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
fn main() {
let counter = AtomicUsize::new(0);
let mut handles = Vec::new();
for _ in 0..10 {
let counter_clone = counter.clone();
let handle = thread::spawn(move || {
for _ in 0..1000 {
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));
}
在上述代码中:
AtomicUsize::new(0)
创建了一个初始值为 0 的原子计数器。fetch_add
方法原子性地增加计数器的值,Ordering::SeqCst
提供了最高级别的内存顺序保证。- 每个线程在独立的环境中执行
fetch_add
操作,避免了锁竞争,确保了线程安全。最后通过load
方法获取最终的计数值。