Golang Sync.Mutex 解析
概念:
“Mutual Exclusion”,传统意义上的“Mutex”
- Mutex用于保证同时只有一个Goroutine能接触到变量,避免冲突。
- Go 的 sync.Mutex 提供两个API:Lock, Unlock。
- 通常用法:声明的 Struct 内放置 Sync.Mutex,修改 Struct 内的参数时,用 Lock 上锁,保证这个参数只被单一goroutine接触。(todo: 如何实现的)
- 使用场景:读写不确定,只有一个读或一个写的场景。
- 可以用 defer 保证 mutex 会被 unlock。
- Point:不能重复 Lock;Unlock 前要 Lock,否则 Panic 警告⚠️;被 Lock 住的 Mutex 可以被其他 Goroutine 解锁。
(TBC)
1. 多个并行Goroutine如何获取锁
锁有两种,正常模式和饥饿模式。
正常模式下,goroutine等待队列遵循先进先出原则,等待被唤醒。被唤醒的goroutine与新请求的goroutine(没进队列)竞争锁。队列中的进程可能要等很久。
饥饿模式下,等待队列的头部goroutine优先级最高,新请求的goroutine被强制放入队列尾部。(猜测会损失调一部分性能,CPU中的goroutine被强制放置play)
对于golang来说,混合使用了两种模式,正常模式下,当队列中等待的goroutine等待时间 > 1ms,会转为饥饿模式。饥饿模式时,当队列中最后一个goroutine也拿到了锁,或拿到锁的时间 < 1ms(即没有积压的goroutine。QA:怎么计时的?)会转回正常模式。
一个Goroutine尝试加锁时,锁的状态?
2. 锁的实现(源码分析)
3. 使用 Example