Go sync.Mutex 源码阅读

sync.Mutex

type Mutex struct {
   state int32   
   sema  uint32
}

//state = 0 未加锁   加锁解锁都是通过原子操作进行修改
//sema      信号量   用于等待队列
image.png

工作模式

  • 正常模式

    • 高吞吐量,自旋线程会抢锁,挂起唤醒少

    一个尝试加锁的goroutine 会先自旋几次,尝试通过原子操作获得锁;如果几次自旋后无法获得,就会加入到信号量队列,按照FIFO进行排队等待,

    当锁被释放,第一个等待着被唤醒后不会立即获得锁,需要与其他自旋goroutine进行竞争, 因为自旋goroutine运行在cpu上且数量多,更容易获得锁;等待着拿不到锁,会重新插入到队列头部

  • 饥饿模式

    • 严格按照排队,可以防止尾端延迟(即最后等待队列 goroutine迟迟获得不到锁)

    当goroutine等待加锁的时间超过1ms,Mutex会切换到饥饿模式

    会把执行unlock的goroutine的锁直接传给 等待队列,其他自旋goroutine会加入到等待队列尾部,进行排队

  • 饥饿模式 ---> 正常模式

    获得锁的goroutine等待时间 小于1ms,

    获得锁的goroutine是等待队列最后一个。

你可能感兴趣的:(Go sync.Mutex 源码阅读)