用法 golang atomic LoadInt32/StoreInt32 (64)

Ole*_*leg 5 go atomicity

任何人都可以展示需要使用此类原子操作的示例。我不明白两者之间的区别

import "sync/atomic"

...
var sharedA int64
var sharedB *int64
...
// concurent code
tmpVarA := sharedA
tmpVarB := *sharedB
// and
tmpVarA := atomic.LoadInt64(&sharedA)
tmpVarB := atomic.LoadInt64(sharedB)
Run Code Online (Sandbox Code Playgroud)

Art*_*Art 7

它根本没有记录在包中,但通常原子加载和正常值的存储不是为了原子性,因为 CPU 操作已经是原子的,而是为了排序。如果您使用原子操作,语言规范或 CPU 指令文档为您提供了关于一个 CPU 存储将被另一个 CPU 看到的顺序的某些保证。如果您不使用正确的(昂贵的)指令,大多数现代 CPU 都没有这样的保证。

因此,在您的示例中(我假设,因为该包没有记录),如果共享变量已由 goroutine 首先写入sharedA,然后sharedB在没有原子操作的情况下读取时,您可能会看到 的更改值sharedB并且仍然是旧值的sharedA。如果存储或加载需要执行额外的魔法来获得正确的排序,在不同的 CPU 系列上是不同的,所以通常语言让你对存储和加载使用原子函数,然后编译器/库知道你的实际 CPU 需要什么。

当然,包没有记录任何这些,所以实际上没有区别,因为我们不知道包实际上保证了什么。因此,对于所有实际目的而言,它是无用的。

  • 我可以想象在 32 位机器上 64 位加载/写入不是原子的。您不想读取未修改的低 32 位和修改后的高 32 位。 (2认同)
  • @Art 包同步的同步和 HB 保证记录在 Go Memory Model 中,例如参见 https://golang.org/ref/mem#tmp_8 。 (2认同)