golang 关于锁 mutex,踩过的坑

£可爱£侵袭症+ 提交于 2019-12-04 23:59:33

伪代码声明:请无视一些拼写错误

  1. mutex实例无需实例化,声明即可使用
func add(){
    var mutex sync.Mutex
    mutex.Lock()
    defer mutex.Unlock()
    fmtPrintln("test lock")
}
  1. mutex在传递给外部使用的时候,需要传指针,不然传的是拷贝,会引起锁失败。并且指针的mutex是一定要实例化过的。
func add() *sync.Mutex{
    var m = &sync.Mutex{}
    return m
}
  1. 对同一个锁,进行多次锁,会死锁
func a(){
    var mutex sync.Mutex
    mutex.Lock()
    mutex.Lock() // dead lock
}
  1. 对一个RWLock进行同时Lock()和RLock()会死锁.
func a(){
    var mutex sync.RWMutex
    mutex.RLock()
    mutex.Lock() // dead lock
}

这意味着如果一个操作函数里同时包含写和读,千万不要这么写

type Object struct{
    Data []interface{}
    L  sync.RWMutex
}
func WR(o Object){
    o.L.Lock()
    defer o.L.UnLock()
    o.Data = append(o.Data, 1)
    
    o.L.RLock()
    defer o.L.RUnLock()
    fmt.Println(o.Data[len(o.Data)-1])
}

因为defer是在return前执行,该段逻辑的锁顺序实际上是 Lock(), RLock(), UnLock(),RUnLock() 死锁了
可以改成:

func WR(o Object){
    func(){
        o.L.Lock()
        defer o.L.UnLock()
        o.Data = append(o.Data, 1)
    }()

    func(){
        o.L.RLock()
        defer o.L.RUnLock()
        fmt.Println(o.Data[len(o.Data)-1])
    }()
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!