5. sync.Cond 原理
sync.Cond 是 Go 语言提供的内置并发安全的条件变量,开箱即用。sync.Cond 的原理非常简单,只有三个方法,Wait、Signal 和 Broadcast。Wait 方法用于等待条件变量,Signal 方法用于唤醒一个等待的协程,Broadcast 方法用于唤醒所有等待的协程。
sync.Cond 的内部结构如下:
type Cond struct {
noCopy noCopy
L Locker
notify notifyList
}
sync.Cond 内部有一个 Locker 接口,同时有一个 notifyList,notifyList 的结构如下:
type notifyList struct {
wait int32
notify int32
lock uintptr
head unsafe.Pointer // *waitNode
tail unsafe.Pointer // *waitNode
}
notifyList 内部有一个 wait 和 notify,分别用于存储等待的协程数和唤醒的协程数,同时有一个 head 和 tail,分别用于存储等待的协程的头和尾。
5.1 sync.Cond 的 Wait 方法
sync.Cond 的 Wait 方法用于等待条件变量,其原型如下:
func (c *Cond) Wait()
Wait 方法的实现非常简单,只有两个步骤:
- 将等待的协程数加 1
- 解锁
- 等待信号量
- 加锁
5.2 sync.Cond 的 Signal 方法
sync.Cond 的 Signal 方法用于唤醒一个等待的协程,其原型如下:
func (c *Cond) Signal()
Signal 方法的实现非常简单,只有两个步骤:
- 将唤醒的协程数加 1
- 唤醒一个等待的协程
5.3 sync.Cond 的 Broadcast 方法
sync.Cond 的 Broadcast 方法用于唤醒所有等待的协程,其原型如下:
func (c *Cond) Broadcast()
Broadcast 方法的实现非常简单,只有两个步骤:
- 将唤醒的协程数加 1
- 唤醒所有等待的协程
6. sync.Cond 的使用
sync.Cond 的使用非常简单,直接声明变量即可,不需要初始化。sync.Cond 的声明如下:
var cond = sync.Cond{}
sync.Cond 的操作如下:
cond.Wait() // 等待条件变量
cond.Signal() // 唤醒一个等待的协程
cond.Broadcast() // 唤醒所有等待的协程
7. sync.Cond 的注意事项
- sync.Cond 不能在创建后再进行复制操作。
- sync.Cond 与其他结构不同,它不是一个结构体,因此我们在声明的时候只需要声明变量即可,不需要初始化。