在Go语言中,对于uint8类型的读写操作是否是原子性的呢?

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

Are reads and writes for uint8 in golang atomic?

问题

关于uint8类型的读写操作,是否是原子操作?

从逻辑上讲,对于一个8位变量的读写应该是一个单个的CPU指令。但是在某些情况下,两个核心可能同时从内存中读取和写入数据,这样可能会导致数据不一致。

英文:

As in the title, are read and write operations regarding uint8, atomic?
Logically it must be a single cpu instruction obviously to read and write for a 8 bit variable. But in any case, two cores could simultaneously read and write from the memory, is it possible to create a stale data this way?

答案1

得分: 10

不。如果你想要原子操作,你可以使用 sync/atomic 包。

如果你的意思是“即使我忽略 Go 的内存模型,8位操作是否是原子的?”,那么答案仍然是,可能不是。

如果硬件保证了读/写操作的原子性,那么它可能是原子的。但这仍然不能保证缓存一致性,或者编译器对操作重新排序的优化。你需要以某种方式对操作进行序列化,使用 Go 提供的原子操作原语,在 goroutine 之间使用“sync”包和通道进行协调。

英文:

No. If you want atomic operations, you can use the sync/atomic package.

If you mean "would 8bit operations be atomic even if I ignore the Go memory model?", then the answer is still, <strike>it depends</strike> probably not.

If the hardware guarantees atomicity of read/write operations, then it might be atomic. But that still doesn't guarantee cache coherence, or compiler optimizations from reordering operations. You need to serialize the operations somehow, with the primitives Go provides in the "atomic" package, and using the "sync" package and channels to coordinate between goroutines.

答案2

得分: 10

在任何平台上,对于原生类型的访问都不能保证是原子的。这就是为什么有 sync/atomic 存在的原因。请参考内存模型文档中的建议

以下是一种通用的原子设置值的示例(Play):

var ax atomic.Value // 可能是全局可访问的

x := uint8(5)

// 原子设置值
ax.Store(x)

x = ax.Load().(uint8)

对于 uint8 类型,可能更高效的解决方案是(Play):

var ax int64 // 可能是全局可访问的

x := uint8(5)

atomic.StoreInt64(&ax, 10)

x = uint8(atomic.LoadInt64(&ax))

fmt.Printf("%T %v\n", x, x)

以上是要翻译的内容。

英文:

There's no guarantee that the access on native types are on any platform atomic. This is why there is sync/atomic. See also the advice in the memory model documentation.

Example for generic way of atomically setting a value (Play)

var ax atomic.Value // may be globally accessible

x := uint8(5)

// set atomically
ax.Store(x)

x = ax.Load().(uint8)

Probably more efficient solution for uint8 (Play):

var ax int64 // may be globally accessible

x := uint8(5)

atomic.StoreInt64(&amp;ax, 10)

x = uint8(atomic.LoadInt64(&amp;ax))

fmt.Printf(&quot;%T %v\n&quot;, x, x)

huangapple
  • 本文由 发表于 2016年3月21日 22:13:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/36133364.html
匿名

发表评论

匿名网友

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

确定