Go語言—sync.Cond原始碼分析
點選這裡,檢視 剩餘 signal 與 broadcast 的解析以及實際舉例
Cond 的主要作用就是獲取鎖之後,wait() 方法會等待一個通知,來進行下一步鎖釋放等操作,以此控制鎖合適釋放,釋放頻率,適用於在併發環境下 goroutine 的等待和通知。
針對 Golang 1.9 的 sync.Cond,與 Golang 1.10 一樣。 原始碼位置:sync\cond.go。
結構體
type Cond struct {
noCopy noCopy // noCopy 可以嵌入到結構中,在第一次使用後不可複製,使用 go vet 作為檢測使用
// 根據需求初始化不同的鎖,如*Mutex 和 *RWMutex
L Locker
notify notifyList // 通知列表,呼叫 Wait() 方法的 goroutine 會被放入 list 中,每次喚醒,從這裡取出
checker copyChecker // 複製檢查,檢查 cond 例項是否被複制
}
再來看看等待佇列 notifyList 結構體:
type notifyList struct {
wait uint32
notify uint32
lock uintptr
head unsafe.Pointer
tail unsafe.Pointer
}
函式
NewCond
相當於 Cond 的建構函式,用於初始化 Cond。
引數為 Locker 例項初始化,傳引數的時候必須是引用或指標,比如&sync.Mutex{}或 new(sync.Mutex),不然會報異常:cannot use lock (type sync.Mutex) as type sync.Locker in argument to sync.NewCond。
大家可以想想為什麼一定要是指標呢? 因為如果傳入 Locker 例項,在呼叫 c.L.Lock() 和 c.L.Unlock() 的時候,會頻繁發生鎖的複製,會導致鎖的失效,甚至導致死鎖。
func NewCond(l Locker) *Cond {
return &Cond{L: l}
}
Wait
等待自動解鎖 c.L 和暫停執行呼叫 goroutine。恢復執行後,等待鎖 c.L 返回之前。與其他系統不同,等待不能返回,除非通過廣播或訊號喚醒。
因為 c。當等待第一次恢復時,L 並沒有被鎖定,呼叫者通常不能假定等待返回時的條件是正確的。相反,呼叫者應該在迴圈中等待:
func (c *Cond) Wait() {
// 檢查 c 是否是被複制的,如果是就 panic
c.checker.check()
// 將當前 goroutine 加入等待佇列
t := runtime_notifyListAdd(&c.notify)
// 解鎖
c.L.Unlock()
// 等待佇列中的所有的 goroutine 執行等待喚醒操作
runtime_notifyListWait(&c.notify, t)
c.L.Lock()
}
關鍵字:go 語言 sync.Cond 原始碼解讀
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go語言——sync.Map原始碼分析Go原始碼
- Go語言Context包原始碼學習GoContext原始碼
- Go 語言效能分析Go
- Go語言的前景分析Go
- 【譯】Go 語言原始碼貢獻官方指導文件Go原始碼
- go rpc 原始碼分析GoRPC原始碼
- go ants原始碼分析Go原始碼
- Go 語言的詞法分析和語法分析(1)Go詞法分析語法分析
- 個人經驗分享如何閱讀Go語言原始碼Go原始碼
- 詳解Go語言排程迴圈原始碼實現Go原始碼
- Go語言————1、初識GO語言Go
- Go的WaitGroup原始碼分析GoAI原始碼
- Go 語言實戰: 編寫可維護 Go 語言程式碼建議Go
- Fabric 1.0原始碼分析(4)Chaincode(鏈碼)#platforms(鏈碼語言平臺)原始碼AIPlatform
- k8s client-go原始碼分析 informer原始碼分析(6)-Indexer原始碼分析K8SclientGo原始碼ORMIndex
- k8s client-go原始碼分析 informer原始碼分析(4)-DeltaFIFO原始碼分析K8SclientGo原始碼ORM
- Uber Go 語言編碼規範Go
- [譯] Go 語言實戰: 編寫可維護 Go 語言程式碼建議Go
- go sync.Map原始碼分析Go原始碼
- GO語言————2、GO語言環境安裝Go
- k8s client-go原始碼分析 informer原始碼分析(5)-Controller&Processor原始碼分析K8SclientGo原始碼ORMController
- 以太坊原始碼分析(44)p2p-database.go原始碼分析原始碼DatabaseGo
- 以太坊原始碼分析(45)p2p-dial.go原始碼分析原始碼Go
- 以太坊原始碼分析(46)p2p-peer.go原始碼分析原始碼Go
- 以太坊原始碼分析(48)p2p-server.go原始碼分析原始碼ServerGo
- 以太坊原始碼分析(49)p2p-table.go原始碼分析原始碼Go
- 以太坊原始碼分析(50)p2p-udp.go原始碼分析原始碼UDPGo
- Go 語言專案程式碼品質Go
- 使用Go語言製作二維碼Go
- Go 語言如何解決程式碼耦合Go
- k8s client-go原始碼分析 informer原始碼分析(1)-概要分析K8SclientGo原始碼ORM
- Go 語言核心知識(一)--- 環境變數和原始碼檔案Go變數原始碼
- Go 語言的詞法分析和語法分析(2)—Import宣告的解析Go詞法分析語法分析Import
- 【Go語言入門系列】(八)Go語言是不是面嚮物件語言?Go物件
- Go_go語言初探Go
- 何為吊炸天的 Golang 程式碼實現分析《Go 語言原本》Golang
- Go語言mapGo
- go 語言切片Go