任何人都可以展示需要使用此类原子操作的示例吗?我不明白之间的区别
import "sync/atomic"
...
var sharedA int64
var sharedB *int64
...
// concurent code
tmpVarA := sharedA
tmpVarB := *sharedB
// and
tmpVarA := atomic.LoadInt64(&sharedA)
tmpVarB := atomic.LoadInt64(sharedB)
它根本没有记录在包中,但通常原子加载和正常值的存储不是为了原子性,因为 CPU 操作已经是原子性的,而是为了排序。如果您使用原子操作,语言规范或 CPU 指令文档会为您提供有关一个 CPU 存储将被另一个 CPU 查看的顺序的某些保证。如果您不使用正确的(昂贵的)指令,大多数现代 CPU 都没有这样的保证。
因此,在您的示例中(我假设,因为该包没有记录),如果共享变量首先由 goroutine 写入sharedA
, then sharedB
,在没有原子操作的情况下阅读 then 时,您可能会看到更改后的值sharedB
仍然是旧值sharedA
。如果存储或加载需要执行额外的魔法才能获得正确的排序,那么在不同的 CPU 系列上情况会有所不同,因此通常语言会让您对存储和加载使用原子函数,然后编译器/库知道您实际的 CPU 需要什么。
当然,这个包没有记录任何这些,所以在实践中没有区别,因为我们不知道这个包实际上保证了什么。因此,对于所有实际目的来说,它都是无用的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)