亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

雙重檢查 golang 中的鎖定 - 為什么需要 mutex.RLock()?

雙重檢查 golang 中的鎖定 - 為什么需要 mutex.RLock()?

Go
收到一只叮咚 2023-06-01 14:05:34
我有一段代碼,它對對象的初始化進行了雙重檢查鎖定。func checkSyncProducer() {? ? mutex.RLock()? ? if syncProducer == nil {? ? ? ? mutex.RUnlock()? ? ? ? mutex.Lock()? ? ? ? defer mutex.Unlock()? ? ? ? if syncProducer == nil {? ? ? ? ? ? syncProducer? = createSyncKafkaProducer() //this func will initialize syncProducer.? ? ? ? }? ? } else {? ? ? ? defer mutex.RUnlock()? ? }}這段代碼在mutex.RLock()第一次 nil 檢查之前。為什么需要這樣?(它在頁面中有解釋,但我無法理解)并且它不會增加開銷,因為每次調用 checkSyncProducer 時都會獲取和釋放讀取鎖。在獲取讀鎖之前是否應該再進行一次 nil 檢查,例如:func checkSyncProducer() {? ? if syncProducer == nil {? ? ? ? mutex.RLock()? ? ? ? if syncProducer == nil {? ? ? ? ? ? mutex.RUnlock()? ? ? ? ? ? mutex.Lock()? ? ? ? ? ? defer mutex.Unlock()? ? ? ? ? ? if syncProducer == nil {? ? ? ? ? ? ? ? createSyncKafkaProducer()? ? ? ? ? ? }? ? ? ? } else {? ? ? ? ? ? defer mutex.RUnlock()? ? ? ? }? ? }}第一個 nil 檢查將確保 RLock 不會被不必要地占用。我對么?
查看完整描述

2 回答

?
慕標5832272

TA貢獻1966條經驗 獲得超4個贊

如果你沒有獲取 RLock 來讀取syncProducer,那就是數據競爭,因為另一個 goroutine 可能會更新它。


如果你假設對指針變量的讀/寫是原子的,這看起來是無害的——活潑的讀syncProducer永遠不會導致不正確的行為。如果你不做這個原子假設,如果你不走運的話,讀取可能只產生指針的一些字節,你的程序就會崩潰。


根據您使用的體系結構、機器字長、編譯器版本等,這可能會也可能不會。但這RLock避免了任何擔憂。


與其顯式地亂用 RWLocks,不如使用它(假設目標是懶惰地初始化一個變量):


var (

    syncOnce sync.Once

    syncProducerInternal *syncProducerType

)


func syncProducer() *syncProducerType {

    syncOnce.Do(func() { syncProducerInternal = createSyncKafkaProducer() })

    return syncProducerInternal

}

然后需要同步生產者的代碼可以調用該syncProducer()函數來獲取它,而永遠不會看到 nil 指針。


查看完整回答
反對 回復 2023-06-01
?
慕萊塢森

TA貢獻1810條經驗 獲得超4個贊

這是必需的,因為檢查是只讀操作。改為執行 RW 鎖是可能的,但這意味著一次只有一個 goroutine 可以進行檢查。



查看完整回答
反對 回復 2023-06-01
  • 2 回答
  • 0 關注
  • 184 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號