Mutex
- sync包提供了互斥量,Once, WaitGroup来保证多线程并发安全
- 比较简单的同步通过sync包,比较复杂的同步建议通过channel来实现
Mutex结构体
- Mutex实际上是互斥锁
- Mutex的初始化状态就是一个没加锁的互斥锁
- Mutex在被加锁之后不允许被复制,也就是带有状态的Mutex不能被复制,否则会给原来的临界数据复制出一把锁
- Mutex包含两个字段
- state
- sema
- Mutex现在有两种状态,normal和starvation
- normal状态下,goroutine是在一个FIFO的队列中排队等待锁的,也就是按照锁的请求时间依次获取锁。但是被唤醒的goroutine并不会立刻拥有mutex,而是需要与新到达的goroutine进行竞争,由于新到达的goroutine已经加载在内存中,所以被唤醒的goroutine大概率会竞争失败,竞争失败之后被唤醒的goroutine会被防止到FIFO的队首。如果一个被唤醒的goroutine在1ms内获取mutex失败,则mutex状态设置为starvation
- starvation状态下,mutex在被当前持有的线程解锁之后,FIFO队列首的goroutine被唤醒并直接拥有改mutex,新到达的goroutine不再尝试获取mutex,也不再自选等待获取锁,而是直接排到队列的队尾
- 如果一个goroutine获取到mutex,如果这个goroutine是队列中的最后一个goroutine或者goroutine等待时间小于1ms,则mutex状态变为noraml状态
- normal状态下性能更好,starvation状态下更加公平,不存在插队和多次获取的情况
|
|
Mutex实现了Locker接口
|
|
- lock方法对mutex加锁
- 如果mutex已经被加锁,尝试加锁的goroutine将会被阻塞直到获取到该锁
|
|
- Unlock完成解锁
|
|