golang 互斥锁的奇葩BUG?

fmt.Println("1.开始加锁" + key)
s.Lock()
fmt.Println("2.加锁完成" + key)

defer fmt.Println("5.解锁完成" + key)
defer s.Unlock()
defer fmt.Println("4.开始解锁" + key)

在前端页面点击菜单,前几次加锁后,解锁一切正常。快速点击菜单或者快速不断刷新页面不出一会儿就会报:fatal error: sync: unlock of unlocked mutex

下面是点击菜单或刷新后的结果:

第一次:

image.png


第二次:

image.png


第三次:

image.png


第四次:

image.png


第五次:

image.png


第六次:

错误来了~~~~

image.png

代码肯定没问题吧,为什么会出现这样错误,我应该怎么调试或者避免这样的奇怪报错。

已解决,但是不太理解,单独抽出来整理一下:

package category

import (
    "sync"
)

type Sync struct {
    Name string
    age  int
    Mu   sync.Mutex
}

var (
    Cache          *Sync
    CacheContainer Sync
)

// GetTree 查询列表
func (s *Sync) GetTree() *Sync {
    s.Mu.Lock()
    defer s.Mu.Unlock()
    Cache = &Sync{
        Name: "abc",
        age:  18,
    }
    // 这里多此一举就出错了,多请求几次就会报:fatal error: sync: unlock of unlocked mutex
    CacheContainer = *Cache
    return &CacheContainer
}

// GetTree2 正确 /**
func (s *Sync) GetTree2() *Sync {
    s.Mu.Lock()
    defer s.Mu.Unlock()
    Cache = &Sync{
        Name: "abc",
        age:  18,
    }
    return Cache
}
阅读 2.1k
2 个回答

你的s是不是全局变量

我猜第一个函数是在Cache上调用,在CacheContainer上应该是每次调用都错误。
Cache跟CacheContainer之间发生了锁复制,然后CacheContainer在其他地方可能锁定跟解锁指向的就不是同一个。
这代码写的也太典了点,习惯不太好。

推荐问题