最近在刷MIT的分布式课程,线程和锁必定是最基本的元素啦.
因为GO自己提倡的Share memory by communicating; don't communicate by sharing memory.
,因此在实现的时候试图不用sharing memory + lock而多用channel来实现,这时候就带来了一些小小的不方便,好比一个字符串s能够被多个goroutine读而被一个goroutine写,显然咱们要将其加锁.
由于不想加锁因而我试图用atomic来解决这个问题,其中有一个Value类型我发现颇有趣,因而决定写下来.数据库
atomic.Value分为两个操做,经过Store()存储Value,经过Load()来读取Value的值.服务器
源码我就不贴了,贴一个关键的struct:分布式
type ifaceWords struct { typ unsafe.Pointer data unsafe.Pointer }
ifaceWords结构体是实际存储咱们的Value值的地方,能够看到,咱们存储的实际是指向Value的type和data的指针.函数
First Store : 当咱们第一次调用Store的时候,Store函数会初始化typ指针(须要注意的是,每个Value在第一次Store以后typ就被肯定而不能更改了,不然会panic).
若是typ==nil则函数会调用runtime_procPin(没找到实现,但注释中说是active spin wait)
随后调用原子操做函数CompareAndSwapPointer(typ, nil, unsafe.Pointer(^uintptr(0))),若是此时结果返回false说明typ已经不等于nil(被其余goroutine修改过),因而调用runtime_procUnpin解锁并从新进行Store过程.
若是原子操做函数返回了true,即typ == nil,那么存储typ以及data的指针.ui
后面的每次Store调用都是直接替换掉data指针this
Load函数检测typ的值,若是为nil或者正在进行首次调用Store则会返回nil.不然返回一个interface{}(实际存储的是ifaceWords值)atom
在MIT的课程中,咱们设计的每个Server都须要访问viewService来得到最新的Primary/Backup数据库服务器视图.
这时候其实对这个View的操做就是周期写,不定时读.这时候就是一个使用Value的合适场景(也可使用原子函数CompareAndSwapPointer).线程
Go官网上给出的例子设计
type Map map[string]string var m Value m.Store(make(Map)) var mu sync.Mutex // used only by writers // read function can be used to read the data without further synchronization read := func(key string) (val string) { m1 := m.Load().(Map) return m1[key] } // insert function can be used to update the data without further synchronization insert := func(key, val string) { mu.Lock() // synchronize with other potential writers defer mu.Unlock() m1 := m.Load().(Map) // load current value of the data structure m2 := make(Map) // create a new value for k, v := range m1 { m2[k] = v // copy all data from the current object to the new one } m2[key] = val // do the update that we need m.Store(m2) // atomically replace the current object with the new one // At this point all new readers start working with the new version. // The old version will be garbage collected once the existing readers // (if any) are done with it. }