## 标签
```routine```、```sync.Mutex```、 ```sync.Cond```
## 场景
利用```sync.Cond```的Broadcast()方法唤醒3个routine
## 过程
**代码**
```golang
package main
import (
"fmt"
"sync"
"time"
)
func main() {
wg := sync.WaitGroup{}
mux := sync.Mutex{}
cond := sync.NewCond(&mux)
wg.Add(3)
for i := 0; i < 2; i++ {
go func(num int) {
defer wg.Done()
fmt.Println("routine", num, "开始处理")
mux.Lock()
fmt.Println(" routine", num, "锁住了mux @", time.Now())
cond.Wait()
fmt.Println(" routine", num, "马上解锁mux @", time.Now())
mux.Unlock()
}(i)
}
go func() {
defer wg.Done()
time.Sleep(time.Second * 10)
fmt.Println("预备,开始!")
cond.Broadcast()
}()
wg.Wait()
}
```
> 逻辑解释
>
> 1、启动2个routine,在每个routine中:
> * 1) 申请锁住mux
>
> * 2) 等待cond的广播信号
>
> * 3) 解锁mux
>
> 2、再启动一个routine,等待10秒后触发cond.Broadcast(),唤醒1.2)之后的操作
**执行结果**
```text
routine 0 开始处理
routine 1 开始处理
routine 0 锁住了mux @ 2020-10-28 18:49:23.1134126 +0800 CST m=+0.003989001
routine 1 锁住了mux @ 2020-10-28 18:49:23.1333588 +0800 CST m=+0.023935201
预备,开始!
routine 1 马上解锁mux @ 2020-10-28 18:49:33.1143597 +0800 CST m=+10.004936101
routine 0 马上解锁mux @ 2020-10-28 18:49:33.1143597 +0800 CST m=+10.004936101
Process finished with exit code 0
```
## 结果分析
从结果看,两个等待的routine在彼此释放锁mux之前都分别获取到了mux的锁,这是比较怪异的地方,让我们来看一下sync.Cond.Wait()方法的逻辑:
```golang
func (c *Cond) Wait() {
c.checker.check()
t := runtime_notifyListAdd(&c.notify)
c.L.Unlock() // 原来幺蛾子出在这儿,在routine执行mux.Unlock()方法之前,sync.Cond先执行了,这就导致另一个routine逮到了机会,锁住了mux
runtime_notifyListWait(&c.notify, t)
c.L.Lock()
}
```
那么问题来了,针对这个场景,应该怎样使用sync.Cond与sync.Mutex配合routine实现最初的目的呢,求大佬科普 ???
有疑问加站长微信联系(非本文作者)