引言
int64MOV
如果一个线程刚写完低32位,还没来得及写高32位时,另一个线程读取了这个变量,那它得到的就是一个毫无逻辑的中间变量,这很有可能使我们的程序出现Bug。
这还只是一个基础类型,如果我们对一个结构体进行赋值,那它出现并发问题的概率就更高了。很可能写线程刚写完一小半的字段,读线程就来读取这个变量,那么就只能读到仅修改了一部分的值。这显然破坏了变量的完整性,读出来的值也是完全错误的。
Goatomic.Valueunsafe.Pointer
atomic.Value的使用方式
atomic.Value
v.Store(c)catomic.Valuevc := v.Load()v
atomic.Value
atomic.Value
atomic.Value的内部实现
atomic.Valueinterface{}
ValueatomicifaceWordsinterface{}interface{}
写入线程安全的保证
直接来看代码
大概的逻辑:
CompareAndSwapLoadPointerValue
atomic.ValuetypdatatypValueruntime_procPin()^uintptr(0)CAStyp^uintptr(0)vdatatyptyptyp^uintptr(0)data
这个逻辑的主要思想就是,为了完成多个字段的原子性写入,我们可以抓住其中的一个字段,以它的状态来标志整个原子写入的状态。
读取(Load)操作
先上代码:
读取相对就简单很多了,它有两个分支:
typ^uintptr(0)typdatainterface{}
总结
atomic.Valueatomic.Value
Mutex