面试题答案
一键面试Rust内存模型基础
- 普通
usize
类型:在Rust中,普通的usize
类型是一种常规的整数类型。它不具备原子性,这意味着多个线程对其进行读写操作时,可能会出现竞态条件。例如,如果一个线程在读取usize
值的过程中,另一个线程同时对其进行修改,就可能导致读取到不一致的值。这是因为普通变量的读写操作没有特殊的内存同步语义,无法保证不同线程之间操作的顺序和可见性。 std::sync::atomic::AtomicUsize
类型:AtomicUsize
是专门为多线程环境设计的类型,它保证了原子性操作。原子操作是不可分割的,在执行过程中不会被其他线程打断。这使得AtomicUsize
在多线程环境下能够保证某些操作之间的happens - before
关系。
原子操作与顺序一致性
- 原子操作:原子操作是指那些在多线程环境下不可分割的操作。对于
AtomicUsize
,像store
(存储值)和load
(加载值)这样的操作都是原子的。这意味着当一个线程执行store
操作时,其他线程要么看到旧值,要么看到新值,不会出现中间状态。 - 顺序一致性(SeqCst):顺序一致性是一种很强的内存序模型。在顺序一致性模型下,所有线程看到的操作顺序是一致的,就好像所有操作都在一个全局的顺序中执行。对于
AtomicUsize
,当使用SeqCst
内存序时,所有的原子操作都按照一个全局的顺序执行,这保证了很强的happens - before
关系。例如,所有线程都能看到store
操作先于load
操作,只要它们按照相同的顺序执行这些操作。
happens - before
关系
- 定义:在Rust内存模型中,
happens - before
关系描述了操作之间的偏序关系。如果操作Ahappens - before
操作B,那么在操作B执行时,操作A的所有效果对操作B都是可见的。对于AtomicUsize
,由于其原子性操作和特定的内存序设置,能够确保不同线程之间的操作满足一定的happens - before
关系。而普通的usize
类型由于没有这些特性,无法保证这种关系。 - 相互作用:原子操作和内存序通过控制不同线程之间的操作顺序和可见性来影响
happens - before
关系。例如,在Relaxed
内存序下,虽然原子操作保证了不可分割性,但对操作顺序和可见性的保证较弱,happens - before
关系也相对较弱。而在SeqCst
内存序下,通过强制全局顺序,加强了happens - before
关系,确保了操作的一致性和可见性。
代码示例
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
fn main() {
let data = AtomicUsize::new(0);
let handle1 = thread::spawn(move || {
data.store(1, Ordering::SeqCst);
});
let handle2 = thread::spawn(move || {
let value = data.load(Ordering::SeqCst);
assert_eq!(value, 1);
});
handle1.join().unwrap();
handle2.join().unwrap();
}
在这个示例中,使用 SeqCst
内存序,store
操作 happens - before
load
操作,因此 load
操作总能看到正确的值 1
。
use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;
fn main() {
let data = AtomicUsize::new(0);
let handle1 = thread::spawn(move || {
data.store(1, Ordering::Relaxed);
});
let handle2 = thread::spawn(move || {
let value = data.load(Ordering::Relaxed);
// 这里可能会断言失败,因为Relaxed内存序不保证load能看到store的最新值
assert_eq!(value, 1);
});
handle1.join().unwrap();
handle2.join().unwrap();
}
在这个使用 Relaxed
内存序的示例中,由于 Relaxed
内存序对操作顺序和可见性保证较弱,load
操作可能看不到 store
操作设置的最新值,因此断言可能会失败,展示了不同内存序下 happens - before
关系的变化以及对程序正确性的影响。