sync/atomic包
Value
在GO语言中, 对于小于64位的基本类型和指针类型, 其赋值操作是原子的, 可以不加锁的进行并发赋值. 但对于复杂的数据结构, 无法保证原子的赋值. Go提供了Value对象来原子的对任意类型赋值. 其Store函数源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| func (v *Value) Store(val any) { if val == nil { panic("sync/atomic: store of nil value into Value") } vp := (*ifaceWords)(unsafe.Pointer(v)) vlp := (*ifaceWords)(unsafe.Pointer(&val)) for { typ := LoadPointer(&vp.typ) if typ == nil { runtime_procPin() if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(&firstStoreInProgress)) { runtime_procUnpin() continue } StorePointer(&vp.data, vlp.data) StorePointer(&vp.typ, vlp.typ) runtime_procUnpin() return } if typ == unsafe.Pointer(&firstStoreInProgress) { continue } if typ != vlp.typ { panic("sync/atomic: store of inconsistently typed value into Value") } StorePointer(&vp.data, vlp.data) return } }
type ifaceWords struct { typ unsafe.Pointer data unsafe.Pointer }
|
上述接口非常巧妙地利用了Go语言中interface{}对象的结构, 用一种简单的方式实现了对象的原子赋值