atomic包中的 Swap、Load、Store 没有锁指令,是如何保证原子性呢?
来源:1-14 Go 并发编程最佳实践
慕丝1411558
2021-06-16 14:45:09
atomic 包中大概有5类方法集, Swap、Load、Store、Add、CAS。一直不理解 load、store 已经是最基本的行为了,怎么还能继续保证原子性呢?
然后我写了个case,使用 go tool compile 查看汇编,在 Swap、Load、Store 中也没有简单 lock 关键字的指令,这个该如何理解呢?
var a int32
var b int32
func main() {
// MOVL $1, AX
// LEAQ "".a(SB), CX
// XCHGL AX, (CX)
// MOVL AX, "".b(SB)
b = atomic.SwapInt32(&a, 1)
// MOVL "".a(SB), AX
// MOVL AX, "".b(SB)
// MOVL $1, "".a(SB)
b, a = a, 1
// MOVL "".a(SB), CX
// MOVL CX, "".b(SB)
b = atomic.LoadInt32(&a)
// MOVL "".a(SB), CX
// MOVL CX, "".b(SB)
b = a
// MOVL $1, CX
// LEAQ "".a(SB), DX
// XCHGL CX, (DX)
atomic.StoreInt32(&a, 1)
// MOVL $1, "".a(SB)
a = 1
// MOVL $1, CX
// LEAQ "".a(SB), DX
// LOCK
// XADDL CX, (DX)
atomic.AddInt32(&a, 1)
// INCL "".a(SB)
a += 1
}
1回答
单个的读写行为并不一定是原子的,只是在 x86 平台上可能是(内存如果没有对齐,可能依然非原子)
同一个原子操作在不同平台可能实现有差别,
比如 x86 平台,内存对齐了,64 位变量读写就是原子的,但在 arm 之类的平台上可能就不是(这里我不确定哦),
读写这种单步操作的原子性是用 mesi 协议保证的,但 cas,add 这种 read-modify-write 多步的操作用 mesi 协议不能保证原子,必须要加 lock 前缀,
https://stackoverflow.com/questions/11065675/lock-prefix-of-intel-instruction-what-is-the-point
对于编程语言这种要跨平台的,同一个指令,
如 atomic.Cas 在不同的平台最终出来的汇编代码应该也是不一样的
相似问题
回答 1
回答 1
回答 1
回答 1
回答 2