如何两次解锁互斥锁

N.F*_*.F. 4 go

两次解锁互斥体是否安全?我的代码:

var m sync.RWMutex = sync.RWMutex{}

func Read() {
    m.RLock()
    defer m.RUnlock()

    // Do something that needs lock
    err := SomeFunction1()
    if err != nil {
        return
    }

    m.RUnlock()

    // Do something that does not need lock
    SomeFunction2()

}
Run Code Online (Sandbox Code Playgroud)

我需要defer m.RUnlock()案例SomeFunction1()返回错误。但是当SomeFunction1()返回没有错误时,m会被m.RUnlock()和解锁两次defer m.RUnlock()

两次解锁互斥体是否安全?如果没有,我应该如何修复我的代码?

ifn*_*tak 5

两次解锁互斥体是否安全?

不,你不应该两次解锁互斥锁。根据文档,这是一个运行时错误

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()
}
Run Code Online (Sandbox Code Playgroud)

在Go Playground上试试吧!