先不讲这个cond是什么,我们从一个场景出发:
有一个慈善机构需要募集善款,目标比方说是100万。那就需要发一个公告,说需要筹集善款100万。群众看到公告就开始捐钱,每个人能力不一样,有的可能1万,有的可能2万,有的人看着不够再捐一笔。为了更快的筹够善款,那肯定是人越多越好,那在计算机世界就是用上所有的cpu资源。很快100万就够了,慈善机构就再发一个公告,说钱够了,大家不用捐了。那这个消息传递可能有延迟,收到的钱比100万多那也没办法,收多少算多少呗,只要能如实公示,正确使用就行了
把上诉场景抽象一下,这个大家一起捐钱,够100万之后就公示的过程就可以用Cond来实现
func main() {
c := sync.NewCond(&sync.Mutex{
})
var ready int //善款总额,单位万
ctx, cancle := context.WithCancel(context.Background())
for i := 0; i < runtime.NumCPU(); i++ {
//尽可能多的人捐款,即充分利用cpu资源
go func(i int) {
for {
select {
case <-ctx.Done():
log.Printf("已经100万了,那我[%v号选手]就不捐了", i)
return
//已经看到公告够了100万了,那就不捐了
default:
//想一下要捐多少
time.Sleep(time.Duration(rand.Int63n(5)) * time.Second)
// 加锁更改等待条件
c.L.Lock()
ad := rand.Intn(5)
if ad == 0 {
//准备捐一个空头账户,那不行,重新捐
c.L.Unlock()
break
}
ready += ad
c.L.Unlock()
log.Printf("[%v号选手]捐了%v万", i,ad)
// 让慈善机构核对一下到100万了没
c.Broadcast()
}
}
}(i)
}
c.L.Lock()
for ready < 100 {
c.Wait()
log.Printf("现在%v万", ready)
}
c.L.Unlock()
log.Println("善款已经够一百万了,不用再捐了")
cancle()
}
这个并发原语用的很少,知道使用场景和怎么用即可
深入了解请参照:Cond:条件变量的实现机制及避坑指南