1. 程式人生 > >Golang讀寫鎖讀鎖重複獲取的問題

Golang讀寫鎖讀鎖重複獲取的問題

遇到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的讀鎖請求排在了寫鎖請求之後

於是死鎖了