Atomic Operations

Compare-and-Swap 操作

先假设没人跟我抢,那么我先拿到旧值,等我计算出新值后,再检查现在的值是不是和我拿到的旧值相等:如果不相等,说明有人抢数据了,那么我就重新试一遍;否则说明没人跟我抢,或者没抢过我,那么我就把新值写入.

Compare Exchange
1
2
3
4
5
6
7
8
9
// val: &AtomicU64
loop {
let old = val.load(Relaxed);
let new = old * 2;
match val.compare_exchange(old, new, Relaxed, Relaxed) {
Ok(_) => ...,
Err(_) => ...,
}
}

CAS 可以确保最终结果正确,但是代价是重试次数可能很多

内存序

  • Relaxed:只保证原子性,不保证顺序
  • Release:release 之前的 write 不会被重排到 release 之后
    • unlock()
  • Acquire:acquire 之后的 read 不会重排到 acquire 之前
    • lock()
  • SeqCst:所有顺序完全一致