62-條件變數結構體Cond
阿新 • • 發佈:2018-11-29
條件變數結構體 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 { } }