日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

条件变量 sync.Cond

發布時間:2023/11/30 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 条件变量 sync.Cond 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

sync.Cond 條件變量是基于互斥鎖的,它必須有互斥鎖的支撐才能發揮作用。

  • sync.Cond 條件變量用來協調想要訪問共享資源的那些線程,當共享資源的狀態發生變化的時候,它可以用來通知被互斥鎖阻塞的線程
  • 條件變量的初始化離不開互斥鎖,并且它的方法也是基于互斥鎖的
  • 條件變量有三個方法,等待通知(wait),單發通知(signal),廣播通知(broadcast)。當互斥鎖鎖定時,可以進行等待通知;當互斥鎖解鎖時,可以進行單發通知和廣播通知。
var mailbox uint8 var lock sync.RWMutex sendCond := sync.NewCond(&lock) recvCond := sync.NewCond(lock.RLocker())

有幾個點需要知道

  • sync.Cond 通過sync.NewCond(sync.Locker)初始化,初始化函數需要一個sync.Locker的參數值
  • sync.Locker其實是一個接口,包含Lock()和Unlock()方法。sync.Mutex和sync.RWMutex都有Lock和Unlock方法,只不過它們都是指針方法。因此,這兩個類型的指針類型才是sync.Locker接口的實現類型
  • 通過lock.RLock()獲得讀鎖,這個讀鎖能調用lock變量的RLock和RUnlock方法,實現對讀鎖的解鎖和鎖定。

生產者,這里看作向mailbox產生值的對象

lock.Lock() for mailbox == 1 {sendCond.Wait() } mailbox = 1 lock.Unlock() recvCond.Signal()

消費者,向mailbox取值的對象

lock.RLock() for mailbox == 0 {recvCond.Wait() } mailbox = 0 lock.RUnlock() sendCond.Signal()

條件變量的Wait方法主要做了四件事。

  • 把調用它的 goroutine(也就是當前的 goroutine)加入到當前條件變量的通知隊列中。
  • 解鎖當前的條件變量基于的那個互斥鎖。
  • 讓當前的 goroutine 處于等待狀態,等到通知到來時再決定是否喚醒它。此時,這個 goroutine 就會阻塞在調用這個Wait方法的那行代碼上。
  • 如果通知到來并且決定喚醒這個 goroutine,那么就在喚醒它之后重新鎖定當前條件變量基于的互斥鎖。自此之后,當前的 goroutine 就會繼續執行后面的代碼了。

if語句只會對共享資源的狀態檢查一次,而for語句卻可以做多次檢查,直到這個狀態改變為止。那為什么要做多次檢查呢?這主要是為了保險起見。如果一個 goroutine 因收到通知而被喚醒,但卻發現共享資源的狀態,依然不符合它的要求,那么就應該再次調用條件變量的Wait方法,并繼續等待下次通知的到來。

在 Go 語言中,我們需要用sync.NewCond函數來初始化一個sync.Cond類型的條件變量。

sync.NewCond函數需要一個sync.Locker類型的參數值。

sync.Mutex類型的值以及sync.RWMutex類型的值都可以滿足這個要求。都可以滿足這個要求。另外,后者的RLocker方法可以返回這個值中的讀鎖,也同樣可以作為sync.NewCond函數的參數值,如此就可以生成與讀寫鎖中的讀鎖對應的條件變量了。

條件變量的Wait方法需要在它基于的互斥鎖保護下執行,否則就會引發不可恢復的 panic。此外,我們最好使用for語句來檢查共享資源的狀態,并包裹對條件變量的Wait方法的調用。

不要用if語句,因為它不能重復地執行”檢查狀態 - 等待通知 - 被喚醒“的這個流程。重復執行這個流程的原因是,一個因等待通知,而被阻塞的 goroutine,可能會在共享資源的狀態不滿足其要求的情況下被喚醒。

條件變量的Signal方法只會喚醒一個因等待通知而被阻塞的 goroutine,而它的Broadcast方法卻可以喚醒所有為此而等待的 goroutine。后者比前者的適應場景要多得多。

這兩個方法并不需要受到互斥鎖的保護,我們也最好不要在解鎖互斥鎖之前調用它們。還有,條件變量的通知具有即時性。當通知被發送的時候,如果沒有任何 goroutine 需要被喚醒,那么該通知就會立即失效。

轉載于:https://www.cnblogs.com/linyihai/p/10253339.html

總結

以上是生活随笔為你收集整理的条件变量 sync.Cond的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。