@sheepbao
2018-08-01T08:53:24.000000Z
字数 2031
阅读 2148
type Y struct {a boolv uint64}func TestAtomicY(t *testing.T) {var y Yatomic.AddUint64(&y.v, 1) // panic in 32bit system}
在上面的例子中,如果在64位系统中运行是没问题的的,但是在32位系统中会panic。
这个简单回答可以查看,go官方的文档atomic-pkt-note的内容:
BugsOn x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX.On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit alignment of 64-bit words accessed atomically. The first word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.
意思就是你如果要在32位系统中用64位的原子操作,必须要自己保证64位对齐,也就是8字节对齐。
如果要看汇编怎么判断的可以查看atomic·Xadd64
最简单的办法就是将所有64位字段放在struct的头部,这样就可以保证8字节对齐,如果你把这个struct嵌入在别的结构体,也要记得嵌入到头部。
package aotmic_testimport ("log""sync/atomic""testing""unsafe")type X struct {v uint64x uint64a boolz uint64y uint32}func TestAtomic(t *testing.T) {var x Xlog.Printf("x.a=%p, offset=%d, alig=%d", &x.a, unsafe.Offsetof(x.a), unsafe.Alignof(x.a))log.Printf("x.v=%p, offset=%d, alig=%d", &x.v, unsafe.Offsetof(x.v), unsafe.Alignof(x.v))log.Printf("x.x=%p, offset=%d, alig=%d", &x.x, unsafe.Offsetof(x.x), unsafe.Alignof(x.x))log.Printf("x.y=%p, offset=%d, alig=%d", &x.y, unsafe.Offsetof(x.y), unsafe.Alignof(x.y))log.Printf("x.z=%p, offset=%d, alig=%d", &x.z, unsafe.Offsetof(x.z), unsafe.Alignof(x.z))log.Printf("x.v=%p", &x.v)atomic.AddUint64(&x.z, 1) // panic}type Y struct {a boolX}func TestAtomicY(t *testing.T) {var y Yx := y.Xatomic.AddUint64(&x.v, 1)atomic.AddUint64(&y.X.v, 1) // panic}type Y2 struct {Xa bool}func TestAtomicY2(t *testing.T) {y := &Y2{}atomic.AddUint64(&y.X.v, 1)}type Temp struct {A byteB [2]byteC int64}func TestAtomicTemp(t *testing.T) {var x Templog.Printf("sizof=%d", unsafe.Sizeof(x))log.Printf("x.A=%p, offset=%d, alig=%d", &x.A, unsafe.Offsetof(x.A), unsafe.Alignof(x.A))log.Printf("x.B=%p, offset=%d, alig=%d", &x.B, unsafe.Offsetof(x.B), unsafe.Alignof(x.B))log.Printf("x.C=%p, offset=%d, alig=%d", &x.C, unsafe.Offsetof(x.C), unsafe.Alignof(x.C))}