sync.Mutex
type Mutex struct {
state int32
sema uint32
}
//state = 0 未加锁 加锁解锁都是通过原子操作进行修改
//sema 信号量 用于等待队列
工作模式
-
正常模式
- 高吞吐量,自旋线程会抢锁,挂起唤醒少
一个尝试加锁的goroutine 会先自旋几次,尝试通过原子操作获得锁;如果几次自旋后无法获得,就会加入到信号量队列,按照FIFO进行排队等待,
当锁被释放,第一个等待着被唤醒后不会立即获得锁,需要与其他自旋goroutine进行竞争, 因为自旋goroutine运行在cpu上且数量多,更容易获得锁;等待着拿不到锁,会重新插入到队列头部
-
饥饿模式
- 严格按照排队,可以防止尾端延迟(即最后等待队列 goroutine迟迟获得不到锁)
当goroutine等待加锁的时间超过1ms,Mutex会切换到饥饿模式
会把执行unlock的goroutine的锁直接传给 等待队列,其他自旋goroutine会加入到等待队列尾部,进行排队
-
饥饿模式 ---> 正常模式
获得锁的goroutine等待时间 小于1ms,
获得锁的goroutine是等待队列最后一个。