Go-Mutex源码解析从自旋到饥饿模式的完整演进
文章导语
"Go的Mutex有几种模式?"------另一个面试高频题。本文将Mutex源码完整拆解,覆盖正常模式、饥饿模式、自旋机制。
一、Mutex状态机
go
// state字段的4部分
// Waiter: 等待者数量(29位)
// Starving: 是否饥饿(1位)
// Woken: 是否唤醒(1位)
// Locked: 是否锁定(1位)
// 正常模式: FIFO等待,新goroutine可自旋抢锁
// 饥饿模式: 等待超过1ms→直接交给队首,无自旋
二、自旋条件
- 多核CPU
- GOMAXPROCS > 1
- P的本地队列为空
- 自旋次数 < 4
三、Lock流程
1. CAS抢锁→成功→结束
2. 自旋抢锁→成功→结束
3. 加入等待队列
4. 被唤醒→获取锁
四、全文总结
正常模式下允许自旋和新goroutine抢锁;等待超过1ms进入饥饿模式,保证公平。
参考文献
- Go源码 sync/mutex.go
- Go 1.9 Mutex优化设计文档