面试题答案
一键面试- 代码实现:
use std::sync::atomic::{AtomicU64, Ordering}; fn main() { let shared_variable = AtomicU64::new(100); let handle = std::thread::spawn(move || { let result = shared_variable.fetch_sub(10, Ordering::SeqCst); println!("Subtracted 10. Old value: {}", result); }); handle.join().unwrap(); }
- 正确性解释:
AtomicU64
类型的fetch_sub
方法是原子操作,这意味着在多线程环境下,该操作不会被其他线程打断。当一个线程调用fetch_sub
时,它会以原子方式减少AtomicU64
变量的值,并返回该变量的旧值。- 由于
fetch_sub
是原子操作,不同线程对该AtomicU64
变量的操作不会相互干扰,从而避免了数据竞争问题。在上述代码中,无论有多少线程同时尝试对shared_variable
进行fetch_sub
操作,每个操作都是独立且正确的。
- 通过
Ordering
枚举优化性能:Ordering
枚举定义了不同的内存顺序。在上述代码中,使用了Ordering::SeqCst
(顺序一致性),它提供了最强的内存顺序保证,但性能相对较低。- 如果在特定场景下,不需要顺序一致性这么强的保证,可以使用较弱的内存顺序来提升性能。例如:
Ordering::Relaxed
:只保证原子操作本身的原子性,不提供任何内存顺序保证。适用于只关心原子变量本身值的场景,如计数器,不关心操作的顺序。Ordering::Acquire
和Ordering::Release
:这两个内存顺序可以用于实现“获取 - 释放”语义。Ordering::Release
用于在写操作时标记,Ordering::Acquire
用于在读操作时标记,它们能保证在释放操作之前的写操作对后续获取操作可见。这种内存顺序在需要保证一定顺序但又不需要顺序一致性那么强保证的场景下能提升性能。