golang?sync.Cond同步機(jī)制運(yùn)用及實(shí)現(xiàn)
sync.Cond
Go同步通信channel
sync.Cond 提供了三個(gè)方法:Wait()、Signal()、Broadcast(),它們的用法如下:
- Wait():阻塞當(dāng)前的 goroutine,等待喚起。
- Signal():?jiǎn)酒鹨粋€(gè)阻塞的 goroutine。
- Broadcast():?jiǎn)酒鹚凶枞?goroutine。
通過(guò)上面的方法描述,我們就可以簡(jiǎn)單的實(shí)現(xiàn)一個(gè)任務(wù)池功能:先批量的創(chuàng)建 goroutine,然后調(diào)用 sync.Cond 的 Wait() 方法讓其阻塞的等待。
當(dāng)有一個(gè)任務(wù)到來(lái)時(shí),則通過(guò) Signal() 喚起剛剛在阻塞的某一個(gè) goroutine,去執(zhí)行任務(wù)。
通過(guò)任務(wù)池功能,我們發(fā)現(xiàn) sync.Cond 的運(yùn)用很簡(jiǎn)單,但 Go 官方并不推薦我們使用 sync.Cond 來(lái)實(shí)現(xiàn)協(xié)程間的同步通信。
因?yàn)樗⒉环?Go 官方 “通過(guò)通信來(lái)共享內(nèi)存” 的設(shè)計(jì)思想,當(dāng)場(chǎng)景復(fù)雜時(shí),則會(huì)耦合各個(gè)業(yè)務(wù)功能。
sync.Cond 源碼分析
我們來(lái)看下 sync.Cond 的結(jié)構(gòu)體,代碼在 /sr/sync/cond.go 下:
type Cond struct {
noCopy noCopy // 不可復(fù)制
L Locker // 鎖
notify notifyList // 通知喚起列表
checker copyChecker // 復(fù)制檢測(cè)
}
可以看到 Cond 上有 notify 列表,而這正是維護(hù)了需要喚起的 goroutine 列表。
當(dāng)我們調(diào)用 Wait() 方法的時(shí)候就會(huì)維護(hù)當(dāng)前 goroutine 到對(duì)應(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í),則會(huì)通過(guò)runtime_notifyListNotifyOne或runtime_notifyListNotifyAll方法來(lái)喚起一個(gè)或多個(gè) goroutine。
其他同步方式的實(shí)現(xiàn)
前面提到到 sync.Cond 并不被推薦作為協(xié)同通信手段,那如果要實(shí)現(xiàn)它的單播、廣播效果,該怎么弄呢?
其實(shí)也很簡(jiǎn)單,如果我們要實(shí)現(xiàn)單播效果,那么只需要通過(guò)阻塞的監(jiān)聽(tīng) channel 信號(hào)即可。
如果要實(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ī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang?urfave/cli庫(kù)簡(jiǎn)單應(yīng)用示例詳解
這篇文章主要為大家介紹了Golang?urfave/cli庫(kù)簡(jiǎn)單應(yīng)用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
golang通過(guò)context控制并發(fā)的應(yīng)用場(chǎng)景實(shí)現(xiàn)
這篇文章主要介紹了golang通過(guò)context控制并發(fā)的應(yīng)用場(chǎng)景實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
向Rust學(xué)習(xí)Go考慮簡(jiǎn)單字符串插值特性示例解析
這篇文章主要為大家介紹了向Rust學(xué)習(xí)Go考慮簡(jiǎn)單字符串插值特性示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
go語(yǔ)法入門(mén)any類(lèi)型的使用場(chǎng)景示例詳解
這篇文章主要為大家介紹了go語(yǔ)法入門(mén)any類(lèi)型的使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
通過(guò)Golang實(shí)現(xiàn)無(wú)頭瀏覽器截圖
在Web開(kāi)發(fā)中,有時(shí)需要對(duì)網(wǎng)頁(yè)進(jìn)行截圖,以便進(jìn)行頁(yè)面預(yù)覽、測(cè)試等操作,本文為大家整理了Golang實(shí)現(xiàn)無(wú)頭瀏覽器的截圖的方法,感興趣的可以了解一下2023-05-05
golang DNS服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)操作
這篇文章主要介紹了golang DNS服務(wù)器的簡(jiǎn)單實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
golang 刪除切片的某個(gè)元素及剔除切片內(nèi)的零值方式
這篇文章主要介紹了golang 刪除切片的某個(gè)元素及剔除切片內(nèi)的零值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
Golang分布式鎖簡(jiǎn)單案例實(shí)現(xiàn)流程
分布式鎖是控制分布式系統(tǒng)之間同步訪問(wèn)共享資源的一種方式。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問(wèn)這些資源時(shí),需要通過(guò)一些互斥手段來(lái)防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了2022-12-12
go語(yǔ)言通過(guò)管道連接兩個(gè)命令行進(jìn)程的方法
這篇文章主要介紹了go語(yǔ)言通過(guò)管道連接兩個(gè)命令行進(jìn)程的方法,實(shí)例分析了Go語(yǔ)言操作命令行進(jìn)程的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03

