golang 中 uint8 的读写是原子的吗?
Are reads and writes for uint8 in golang atomic?
如题,uint8的读写操作是原子的吗?
从逻辑上讲,显然它必须是单个 cpu 指令才能读取和写入 8 位变量。但是无论如何,两个核心可以同时从内存中读取和写入,这样是否可以创建一个陈旧的数据?
没有。如果你想要原子操作,你可以使用 sync/atomic
包。
如果你的意思是"would 8bit operations be atomic even if I ignore the Go memory model?",那么答案仍然是,这取决于可能不是。
如果硬件保证read/write操作的原子性,那么它可能是原子的。但这仍然不能保证缓存一致性,或重新排序操作的编译器优化。您需要以某种方式序列化操作,使用 Go 在 "atomic" 包中提供的原语,并使用 "sync" 包和通道在 goroutine 之间进行协调。
不能保证对本机类型的访问在任何平台上都是原子的。这就是为什么有 sync/atomic
. See also the advice in the memory model documentation.
原子设置值的通用方法示例 (Play)
var ax atomic.Value // may be globally accessible
x := uint8(5)
// set atomically
ax.Store(x)
x = ax.Load().(uint8)
uint8
(Play) 的可能更有效的解决方案:
var ax int64 // may be globally accessible
x := uint8(5)
atomic.StoreInt64(&ax, 10)
x = uint8(atomic.LoadInt64(&ax))
fmt.Printf("%T %v\n", x, x)
如题,uint8的读写操作是原子的吗? 从逻辑上讲,显然它必须是单个 cpu 指令才能读取和写入 8 位变量。但是无论如何,两个核心可以同时从内存中读取和写入,这样是否可以创建一个陈旧的数据?
没有。如果你想要原子操作,你可以使用 sync/atomic
包。
如果你的意思是"would 8bit operations be atomic even if I ignore the Go memory model?",那么答案仍然是,这取决于可能不是。
如果硬件保证read/write操作的原子性,那么它可能是原子的。但这仍然不能保证缓存一致性,或重新排序操作的编译器优化。您需要以某种方式序列化操作,使用 Go 在 "atomic" 包中提供的原语,并使用 "sync" 包和通道在 goroutine 之间进行协调。
不能保证对本机类型的访问在任何平台上都是原子的。这就是为什么有 sync/atomic
. See also the advice in the memory model documentation.
原子设置值的通用方法示例 (Play)
var ax atomic.Value // may be globally accessible
x := uint8(5)
// set atomically
ax.Store(x)
x = ax.Load().(uint8)
uint8
(Play) 的可能更有效的解决方案:
var ax int64 // may be globally accessible
x := uint8(5)
atomic.StoreInt64(&ax, 10)
x = uint8(atomic.LoadInt64(&ax))
fmt.Printf("%T %v\n", x, x)