sync.Mutex是一个不可重入的排他锁。 这点和Java不同,golang里面的排它锁是不可重入的。
当一个 goroutine 获得了这个锁的拥有权后, 其它请求锁的 goroutine 就会阻塞在 Lock 方法的调用上,直到锁被释放。
数据结构与状态机
sync.Mutex 由两个字段 state 和 sema 组成。其中 state 表示当前互斥锁的状态,而 sema 是用于控制锁状态的信号量。
type Mutex struct {
state int32
sema uint32
}
需要强调的是Mutex一旦使用之后,一定不要做copy操作。
Mutex的状态机比较复杂,使用一个int32来表示:
const (
mutexLocked = 1 << iota // mutex is locked
mutexWoken //2
mutexStarving //4
mutexWaiterShift = iota //3
)
32 3 2 1 0
| | | | |
| | | | |
v-----------------------------------------------v-------------v-------------v-------------+
| | | | v
| waitersCount |mutexStarving| mutexWoken | mutexLocked |
| | | | |
+-----------------------------------------------+-------------+--------