引言

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