Golang讀寫鎖讀鎖重複獲取的問題
阿新 • • 發佈:2018-12-20
遇到Golang的sync.RWMutex的一個坑,同一個協程重複獲取讀鎖導致的死鎖為題。
程式碼如下
var (
l sync.RWMutex
)
func f1() {
l.RLock()
defer l.RUnlock()
f2()
// ...
}
func f2() {
l.RLock()
defer l.RUnlock()
// ...
}
大概就是,一個函式裡面獲取讀鎖,然後呼叫另一個函式,另一個函式也去獲取讀鎖,然後還有其他協程獲取寫鎖。結果就出現死鎖了。
godoc的說明如下:
If a goroutine holds a RWMutex for reading and another goroutine might call Lock, no goroutine should expect to be able to acquire a read lock until the initial read lock is released. In particular, this prohibits recursive read locking. This is to ensure that the lock eventually becomes available; a blocked Lock call excludes new readers from acquiring the lock.
大意就是,寫鎖優先順序更高,一旦有了寫鎖的請求,新來的讀鎖的請求都得排在後面。
於是就會出現這個時序:
1、f1獲取到了讀鎖
2、在呼叫f2之前其他協程申請寫鎖
3、f2的讀鎖請求排在了寫鎖請求之後
於是死鎖了