登录
首页 >  Golang >  Go问答

如何在释放延迟读锁之前正确释放 RWMutex 的最佳做法是什么?

来源:stackoverflow

时间:2024-02-27 13:54:27 471浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《如何在释放延迟读锁之前正确释放 RWMutex 的最佳做法是什么?》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

我正在开发数据库,​​我想知道解决此问题的最佳方法。

基本上,我想在函数的早期解锁读取互斥锁,因为最后一位是并发安全的。

func (s *structure) get(key interface{}, object interface{}) (found bool, err error ){
    s.rlock()
    defer s.runlock()

    // concurrent-dangerous stuff begins
    ref, err := s.index.getoneequals(string(s.structname), key)
    if err != nil {
        return false, err
    }

    path := ref.topath(s.structname)
    if (path == nil) {
        return false, nil
    }

    value, err := dbdrivers.db.get(path)
    if err != nil {
        return false, err
    }
    // concurrent-dangerous stuff ends
    // runlock should technically be here

    err = encoding.marshaler.unmarshal(value, object)
    if err != nil {
        return false, err
    }
}

如果我只是在底部添加一个 s.runlocked (其中说 runlocked 技术上应该在这里),同时保留延迟语句,如果我理解正确,它将导致问题。据我了解,runlock 通过计数器工作。因此,如果我的程序超出了该点(“runlocked 从技术上讲应该在这里”),它会在函数结束时调用 s.runlocked 延迟的 s.runlocked 。因此计数器会递减两次,这可能会导致灾难。

因此,我能想到的唯一解决方案是这个 - 这是乞求陷阱,因为我需要考虑函数可以结束的所有地方:

func (s *Structure) Get(key interface{}, object interface{}) (found bool, err error ){
    s.RLock()

    // Concurrent-dangerous stuff begins
    ref, err := s.Index.GetOneEquals(string(s.StructName), key)
    if err != nil {
        s.RUnlock() // <----
        return false, err
    }

    path := ref.ToPath(s.StructName)
    if (path == nil) {
        s.RUnlock() // <----
        return false, nil
    }

    value, err := dbdrivers.DB.Get(path)
    if err != nil {
        s.RUnlock() // <----
        return false, err
    }
    // Concurrent-dangerous stuff ends
    // RUnlock should technically be here
    s.RUnlock() // <----

    err = encoding.Marshaler.Unmarshal(value, object)
    if err != nil {
        return false, err
    }
}

有更安全的方法吗?


正确答案


如果将内部块放入其自己的函数中,您仍然可以使用 defer

func (s *Structure) Get(key interface{}, object interface{}) (found bool, err error ){

    s.RLock()
    failed, found, err:= func() {
      defer s.RUnlock()
         ref, err := s.Index.GetOneEquals(string(s.StructName), key)
         if err != nil {
            return true, false, err
         }
         // Do stuff
         return false, found, nil
    }()
    if failed {
      return found, err
    }
    // continue function, lock is unlocked
}

理论要掌握,实操不能落!以上关于《如何在释放延迟读锁之前正确释放 RWMutex 的最佳做法是什么?》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>