golang?sync.Cond同步機(jī)制運(yùn)用及實(shí)現(xiàn)
sync.Cond
Go同步通信channel
sync.Cond 提供了三個(gè)方法:Wait()、Signal()、Broadcast(),它們的用法如下:
- Wait():阻塞當(dāng)前的 goroutine,等待喚起。
- Signal():喚起一個(gè)阻塞的 goroutine。
- Broadcast():喚起所有阻塞的 goroutine。
通過上面的方法描述,我們就可以簡單的實(shí)現(xiàn)一個(gè)任務(wù)池功能:先批量的創(chuàng)建 goroutine,然后調(diào)用 sync.Cond 的 Wait() 方法讓其阻塞的等待。
當(dāng)有一個(gè)任務(wù)到來時(shí),則通過 Signal() 喚起剛剛在阻塞的某一個(gè) goroutine,去執(zhí)行任務(wù)。
通過任務(wù)池功能,我們發(fā)現(xiàn) sync.Cond 的運(yùn)用很簡單,但 Go 官方并不推薦我們使用 sync.Cond 來實(shí)現(xiàn)協(xié)程間的同步通信。
因?yàn)樗⒉环?Go 官方 “通過通信來共享內(nèi)存” 的設(shè)計(jì)思想,當(dāng)場景復(fù)雜時(shí),則會耦合各個(gè)業(yè)務(wù)功能。
sync.Cond 源碼分析
我們來看下 sync.Cond 的結(jié)構(gòu)體,代碼在 /sr/sync/cond.go 下:
type Cond struct { noCopy noCopy // 不可復(fù)制 L Locker // 鎖 notify notifyList // 通知喚起列表 checker copyChecker // 復(fù)制檢測 }
可以看到 Cond 上有 notify 列表,而這正是維護(hù)了需要喚起的 goroutine 列表。
當(dāng)我們調(diào)用 Wait() 方法的時(shí)候就會維護(hù)當(dāng)前 goroutine 到對應(yīng)的 notifyList 里:
func (c *Cond) Wait() { c.checker.check() t := runtime_notifyListAdd(&c.notify) // 將當(dāng)前 goroutine 添加到 notifyList 里 c.L.Unlock() runtime_notifyListWait(&c.notify, t) // 阻塞等待 c.L.Lock() }
當(dāng)有其他協(xié)程調(diào)用了 Signal 或 Broadcast 方法時(shí),則會通過runtime_notifyListNotifyOne
或runtime_notifyListNotifyAll
方法來喚起一個(gè)或多個(gè) goroutine。
其他同步方式的實(shí)現(xiàn)
前面提到到 sync.Cond 并不被推薦作為協(xié)同通信手段,那如果要實(shí)現(xiàn)它的單播、廣播效果,該怎么弄呢?
其實(shí)也很簡單,如果我們要實(shí)現(xiàn)單播效果,那么只需要通過阻塞的監(jiān)聽 channel 信號即可。
如果要實(shí)現(xiàn)廣播喚起效果,只需要利用 context 的鏈?zhǔn)饺∠匦?,也能達(dá)到該效果。
以上就是golang sync.Cond同步機(jī)制運(yùn)用及實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于golang sync.Cond同步機(jī)制的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Go語言使用templ實(shí)現(xiàn)編寫HTML用戶界面
templ是一個(gè)在 Go 中編寫 HTML 用戶界面的語言,使用 templ,我們可以創(chuàng)建可呈現(xiàn) HTML 片段的組件,下面就跟隨小編一起了解一下具體的實(shí)現(xiàn)方法吧2023-12-12在ubuntu下安裝go開發(fā)環(huán)境的全過程
Go語言是谷歌公司開發(fā)的編程語言,雖然安裝和配置go很簡單,但是很多初學(xué)者在第一次安裝go環(huán)境時(shí)會遇到各種坑,下面這篇文章主要給大家介紹了關(guān)于在ubuntu下安裝go開發(fā)環(huán)境的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08golang字符串轉(zhuǎn)64位整數(shù)的示例代碼
這篇文章主要介紹了golang字符串轉(zhuǎn)64位整數(shù),在Go語言中,可以使用strconv包中的ParseInt函數(shù)將字符串轉(zhuǎn)換為64位整數(shù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09Go?gRPC進(jìn)階教程服務(wù)超時(shí)設(shè)置
這篇文章主要為大家介紹了Go?gRPC進(jìn)階,gRPC請求的超時(shí)時(shí)間設(shè)置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06一文帶你學(xué)會使用Go語言實(shí)現(xiàn)自己的MCP服務(wù)端
這篇文章將帶大家速覽MCP的核心概念,并以Go語言為例,介紹如何開發(fā)MCP服務(wù)端和客戶端,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2025-04-04