近日看了一篇 文章,讲到了用锁的 panic 问题,但并没有看懂,今日测试了许多场景,认为终于得出了结论:
- 读写锁中的可读锁(
sync.RWMutex 的 RLock())可以嵌套使用的。
- 互斥锁(
sync.Mutex 和 sync.RWMutex 的 Lock())是不可以互相嵌套的,且不可以与可读锁嵌套。
之前我在读写锁和互斥锁上理解有偏差,认为读写锁与互斥锁是完全独立且相互对应的关系。现在理解为 互斥 只是一种特性。而把 sync.Mutex 叫作 全局锁, sync.RWMutex 叫作 读写锁。
全局锁 sync.Mutex,是同一时刻某一资源只能上一个锁,此锁具有排他性,上锁后只能被此线程使用,直至解锁。加锁后即不能读也不能写。全局锁是互斥锁,即 sync.Mutex 是个互斥锁。
读写锁 sync.RWMutex ,将使用者分为读者和写者两个概念,支持同时多个读者一起读共享资源,但写时只能有一个,并且在写时不可以读。理论上来说,sync.RWMutex 的 Lock() 也是个互斥锁。
踩坑点
将上面的结论展开一下,更清晰得说(为避免理解偏差宁可唠叨一些):
sync.Mutex 的锁是不可以嵌套使用的。
sync.RWMutex 的 mu.Lock() 是不可以嵌套的。
sync.RWMutex 的 mu.Lock() 中不可以嵌套 mu.RLock()。(这是个注意的地方)
否则,会 panic fatal error: all goroutines are asleep - deadlock!
来源:https://studygolang.com/articles/25870
「三年博客,如果觉得我的文章对您有用,请帮助本站成长」
共有 0 - golang中的锁