多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] > [参考](https://mp.weixin.qq.com/s?__biz=MzAxMTA4Njc0OQ==&mid=2651438345&idx=3&sn=b03e06d6bef1de2bcae561e8f607e0d4&chksm=80bb63fbb7cceaedf344010a30547122b2912d806763f268dbd4eea55a079936fe16ab55c8ed&scene=21#wechat_redirect) ## 原子性 cpu 在操作中不会切换任务的最小操作单元叫做原子,在并发系统中采用原子才可避免使用互斥锁 ## 语法 ``` // 获取 func LoadInt32(addr *int32) (val int32) func LoadInt64(addr *int64) (val int64) func LoadUint32(addr *uint32) (val uint32) func LoadUint64(addr *uint64) (val uint64) func LoadUintptr(addr *uintptr) (val uintptr) func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) // 赋值 func StoreInt32(addr *int32, val int32) func StoreInt64(addr *int64, val int64) func StoreUint32(addr *uint32, val uint32) func StoreUint64(addr *uint64, val uint64) func StoreUintptr(addr *uintptr, val uintptr) func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) // 增加 func AddInt32(addr *int32, delta int32) (new int32) func AddInt64(addr *int64, delta int64) (new int64) func AddUint32(addr *uint32, delta uint32) (new uint32) func AddUint64(addr *uint64, delta uint64) (new uint64) func AddUintptr(addr *uintptr, delta uintptr) (new uintptr) // 交换两个值,并返回旧的值 func SwapInt32(addr *int32, new int32) (old int32) func SwapInt64(addr *int64, new int64) (old int64) func SwapUint32(addr *uint32, new uint32) (old uint32) func SwapUint64(addr *uint64, new uint64) (old uint64) func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) // 原子性的比较*addr和old,如果相同则将new赋值给*addr并返回真 func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool) func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool) func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool) func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool) func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) ``` ## 实例 ### 原子操作 ``` var i int32 atomic.StoreInt32(&i, 3) // i=3 atomic.AddInt32(&i, 1) // i=4 l := atomic.LoadInt32(&i) fmt.Printf("%+v\n", l) // 4 var j int32 j = 11 res := atomic.SwapInt32(&i, j) // i=11 fmt.Printf("%+v\n", res) // 4 atomic.CompareAndSwapInt32(&i, 11, 12) // i=12 ``` ## atomic.Value 注意: 1. 存储值不能是 nil; 2. 再次存储时,值类型必须相等 如果违背这两条,编译时会抛出 panic ``` type People struct { Name string } p := People{ Name: "ccc", } var a atomic.Value a.Store(p) l := a.Load().(People) fmt.Printf("%+v\n", l.Name) ``` ### 当作mpa