Cond--条件变量并发原语

先不讲这个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:条件变量的实现机制及避坑指南

猜你喜欢

转载自blog.csdn.net/csdniter/article/details/111043617
今日推荐