3 回答

TA貢獻2012條經驗 獲得超12個贊
兩次解鎖互斥體是否安全?
不,你不應該兩次解鎖互斥體。根據文檔,這是一個運行時錯誤。
RUnlock 撤消單個 RLock 調用;它不會影響其他同時閱讀的讀者。如果 rw 在進入 RUnlock 時未鎖定以進行讀取,則這是一個運行時錯誤。
如果沒有,我應該如何修復我的代碼?
我建議保留defer
但僅m.RUnlock()
在發生錯誤時才保留。如果您在SomeFunction1()
和之間添加更多函數調用,這可以輕松擴展SomeFunction2()
。
func Read() {
? ? var err error
? ? m.RLock()
? ? defer func() {
? ? ? ? if err != nil {
? ? ? ? ? ? m.RUnlock()
? ? ? ? }
? ? }()
? ??
? ? // Do something that needs lock
? ? err = SomeFunction1()
? ? if err != nil {
? ? ? ? return
? ? }
? ? m.RUnlock()
? ? // Do something that does not need lock
? ? SomeFunction2()
}
在Go Playground上試試吧!

TA貢獻1828條經驗 獲得超3個贊
解鎖未鎖定的互斥鎖會導致恐慌。
您可以簡單地刪除defer并將其添加到 if 條件中:
var m sync.RWMutex = sync.RWMutex{}
func Read() {
m.RLock()
// Do something that needs lock
err := SomeFunction1()
if (err != nil) {
m.RUnlock()
return
}
m.RUnlock()
// Do something that does not need lock
SomeFunction2()
}
或者甚至更好(對可讀性影響較?。?/p>
func Read() {
m.RLock()
err := SomeFunction1()
m.RUnlock()
if (err != nil) {
return
}
SomeFunction2()
}

TA貢獻1744條經驗 獲得超4個贊
來自戈多克:
如果 m 在進入 Unlock 時未鎖定,則會發生運行時錯誤。
所以,不要這樣做。
最簡單的解決方法是不使用延遲解鎖,而是在每個可能的出口處解鎖?;蛘?,你也可以這樣做,但不太容易閱讀:
func Read() {
if err := func() {
m.RLock()
defer m.RUnlock()
// Do something that needs lock
err := SomeFunction1()
if err != nil {
return err
}(); err != nil {
return err
}
// Do something that does not need lock
SomeFunction2()
}
- 3 回答
- 0 關注
- 174 瀏覽
添加回答
舉報