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.如果一個函數讀鎖定讀/寫互斥的兩倍,而另一個函數寫鎖,然后直寫未鎖相同的互斥體,原有的功能仍然掛起。這是為什么?是不是因為互斥體允許代碼執行有一個串行順序?我剛剛通過刪除第二mu.RLock()行解決了這樣的場景(我花了幾個小時來查明)。
1 回答

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