var mu sync.RWMutexgo func() { mu.RLock() defer mu.RUnlock() mu.RLock() // In my real scenario this second lock happened in a nested function. defer mu.RUnlock() // More code.}()mu.Lock()mu.Unlock() // The goroutine above still hangs.如果一個(gè)函數(shù)讀鎖定讀/寫互斥的兩倍,而另一個(gè)函數(shù)寫鎖,然后直寫未鎖相同的互斥體,原有的功能仍然掛起。這是為什么?是不是因?yàn)榛コ怏w允許代碼執(zhí)行有一個(gè)串行順序?我剛剛通過刪除第二mu.RLock()行解決了這樣的場景(我花了幾個(gè)小時(shí)來查明)。
1 回答

catspeake
TA貢獻(xiàn)1111條經(jīng)驗(yàn) 獲得超0個(gè)贊
這是讀寫鎖的幾種標(biāo)準(zhǔn)行為之一。什么維基百科稱之為“寫寧愿RW鎖”。
的文檔sync's
RWMutex.Lock
說:
為確保鎖最終可用,阻塞的 Lock 調(diào)用將新讀者排除在獲取鎖之外。
否則,在前一個(gè)釋放之前,每個(gè)讀取鎖都獲得了讀取鎖的一系列讀取器可能會無限期地使寫入饑餓。
這意味著調(diào)用同一個(gè) goroutine 已經(jīng)讀鎖定的RLock
a總是不安全的RWMutex
。(順便說一下,這也適用Lock
于常規(guī)互斥鎖,因?yàn)?Go 的互斥鎖不支持遞歸鎖定。)
它不安全的原因是,如果 goroutine 阻止獲取第二個(gè)讀鎖(由于被阻塞的寫入器),它將永遠(yuǎn)不會釋放第一個(gè)讀鎖。這將導(dǎo)致對互斥鎖的每個(gè)未來鎖調(diào)用永遠(yuǎn)阻塞,導(dǎo)致程序的一部分或全部死鎖。如果所有 goroutine 都被阻塞,Go 只會檢測到死鎖。
- 1 回答
- 0 關(guān)注
- 259 瀏覽
添加回答
舉報(bào)
0/150
提交
取消