Golang锁

RWMutex 读写锁:

​ 内部需要维护一个复杂的内部记录。所以适用于并发读取,修改操作比较少的情况,相反,竞争较低相较于互斥锁性能较慢。

​ Mutex 互斥锁:不可重入

​ 不可重入的原因:互斥量的目的是为了确保共享变量在程序执行时的关键点上能够保证不变性。不变性的其中之一是“没有goroutine访问共享变量”。

​ 但实际上对于mutex保护的变量来说,不变性还包括其它方面。当一个goroutine获得了一个互斥锁时,它会断定这种不变性能够被保持。其获取并保持锁期间,可能会去更新共享变量,这样不变性只是短暂地被破坏。然而当其释放锁之后,它必须保证不变性已经恢复原样。

​ 尽管一个可以重入的mutex也可以保证没有其它的goroutine在访问共享变量,但这种方式没法保证这些变量额外的不变性。

总结:互斥锁中的互斥量要保证共享变量的不变性,可重入锁可以保证没有其他的goroutine访问共享变量,但不能保证额外变量的不变性。

Mutex锁的实现

  1. 加锁
  2. 解锁
// sync.Once()  TODO
type Once struct {
 m    Mutex
 done uint32
}
func (o *Once) Do(f func()) {
 if atomic.LoadUint32(&o.done) == 1 {
     return
 }
 o.m.Lock()
 defer o.m.Unlock()
 if o.done == 0 {
     defer atomic.StoreUint32(&o.done, 1)
     f() // 只执行一次
 }
}