62-条件变量结构体Cond

 




条件变量结构体
Cond


先看一下Cond的源码

type Cond struct {
	noCopy noCopy

	// L is held while observing or changing the condition
	L Locker        // 在条件变量中有把锁

	notify  notifyList
	checker copyChecker
}


条件变量结构体中有一把锁
所以条件变量就可以有加锁和解锁的功能


再说一下条件变量Cond的方法

方法一:func (c *Cond) Wait():  


方法二:func (c *Cond) Signal():唤醒一个人


方法三:func (c *Cond) Broadcast():唤醒所有的人(惊群)



wait的功能有三个


1、阻塞


2、解锁


3、加锁


说一下方法的具体细节

1.wait一旦阻塞,就不会自动去抢锁
需要被唤醒后才能去抢锁
wait需要被signal或者broadcast唤醒

wait解锁并且阻塞当前的线程
需要调用broadcast或者signal唤醒后
线程才恢复执行
不会主动醒过来

2.signal唤醒等待c的一个线程
在调用这个方法的时候,建议是保持c.L的锁定
单发通知: 给一个wait的线程发送通知

3.broadcast唤醒所有wait的线程,建议保持锁定
广播通知: 给所有wait的线程发送通知


我们来一个例子


var cond sync.Cond				//条件变量
//生产者
func producer(in chan<- int){
	for  {
		cond.L.Lock()
		for len(in)==3{
			cond.Signal()
			cond.Wait()	//阻塞——解锁——加锁
		}
		num:=rand.Intn(100)
		fmt.Println("生产了",num)
		in<-num
		//cond.Broadcast()		//惊群
		cond.L.Unlock()
	}
}
//消费者
func consumer(out <-chan int )  {
	for  {
		cond.L.Lock()
		for len(out)==0{
			cond.Signal()
			cond.Wait()		//阻塞——解锁——加锁
		}
		num:=<-out
		fmt.Println("消费了:",num)
		//cond.Broadcast()		//惊群
		cond.L.Unlock()
	}
}

func main() {
	rand.Seed(time.Now().UnixNano())		//随机种子
	cond.L=new(sync.Mutex)					//条件变量中的锁
	c:=make(chan int,3)						//缓冲区
	for i:=1;i<=5 ;i++  {					//5个协程并发生产
		go producer(c)
	}
	for i:=1;i<=5 ;i++  {					//5个协程并发消费
		go consumer(c)
	}
	select {

	}
}







 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值