62-条件变量结构体Cond

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33781658/article/details/84503096



条件变量结构体
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 {

	}
}







猜你喜欢

转载自blog.csdn.net/qq_33781658/article/details/84503096
62-
今日推荐