使用Golang的原子操作LoadInt32/StoreInt32(64)的用法。

huangapple go评论75阅读模式
英文:

usage golang atomic LoadInt32/StoreInt32 (64)

问题

有人可以展示一下需要使用原子操作的示例吗?我不理解下面代码中的区别:

import "sync/atomic"

...
var sharedA int64
var sharedB *int64
...
// 并发代码
tmpVarA := sharedA
tmpVarB := *sharedB
// 和
tmpVarA := atomic.LoadInt64(&sharedA)
tmpVarB := atomic.LoadInt64(sharedB)
英文:

Can anybody show the example where usage of such atomic operations needed. I don't understand a differenece between

import "sync/atomic"

...
var sharedA int64
var sharedB *int64
...
// concurent code
tmpVarA := sharedA
tmpVarB := *sharedB
// and
tmpVarA := atomic.LoadInt64(&sharedA)
tmpVarB := atomic.LoadInt64(sharedB)

答案1

得分: 8

在包的文档中没有对此进行任何记录,但通常情况下,普通值的原子加载和存储并不是为了原子性,因为CPU操作已经是原子的,而是为了排序。语言规范或CPU指令文档会给出一定的保证,即如果使用原子操作,一个CPU存储的顺序将如何被另一个CPU看到。如果不使用适当的(昂贵)指令,大多数现代CPU都无法提供这样的保证。

因此,在您的示例中(我假设,因为该包没有文档),如果共享变量首先被一个goroutine写入sharedA,然后是sharedB,那么在没有原子操作的情况下,您可能会看到sharedB的更改值,但仍然是sharedA的旧值。在不同的CPU系列上,存储或加载是否需要执行额外的操作以正确排序是不同的,因此通常语言会要求您对存储和加载都使用原子函数,这样编译器/库就知道您的实际CPU需要什么。

当然,该包没有对此进行任何文档记录,因此在实践中没有任何区别,因为我们不知道该包实际上提供了什么保证。因此,从实际目的来看,它是无用的。

英文:

It's not documented in the package at all, but normally atomic loads and stores of normal values are there not for atomicity because the CPU operations are already atomic, but for ordering. The language specification or CPU instruction documentation gives you certain guarantees about in which order one CPU stores will be seen by another CPU if you use the atomic operations. Most modern CPUs have no such guarantees if you don't use the proper (expensive) instructions for it.

So in your example (I assume, since the package isn't documented), if the shared variables have been written by a goroutine first to sharedA, then sharedB, when reading then without atomic operations you might see the changed value of sharedB and still the old value of sharedA. It's different on different CPU families if the stores or loads need to perform extra magic to get the ordering right, so usually languages make you use atomic functions for both stores and loads and then the compiler/library knows what your actual CPU needs.

Of course, the package doesn't document any of this, so in practice there is no difference because we don't know what the package actually guarantees. So for all practical purposes it's useless.

huangapple
  • 本文由 发表于 2015年11月5日 18:47:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/33542609.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定