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()
}
或者甚至更好(对可读性影响较小):
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 关注
- 116 浏览
添加回答
举报