02 | Mutex:庖丁解牛看实现
该思维导图由 AI 生成,仅供参考
- 深入了解
- 翻译
- 解释
- 总结
Go语言中的Mutex(互斥锁)实现经历了多个阶段的演进,从最初的简单实现到逐步提升性能和公平性。文章介绍了Mutex的初版实现,使用CAS操作对锁进行标记,以及对Unlock方法的讨论。随后,文章提到了对Mutex的微调和性能优化,以及对defer的优化使用。此外,还探讨了如何解决请求锁的goroutine排队等待获取互斥锁的性能问题。通过本文,读者可以深入了解Mutex的演进历程,体验技术追求的美妙,以及对复杂度、性能、结构设计的权衡考量。文章内容涵盖了Mutex的实现细节和性能优化,对于想要深入了解并发编程的读者具有很高的参考价值。文章通过对Mutex的不同阶段实现的详细介绍,展现了Go语言中对并发控制的不断优化和迭代,为读者呈现了技术演进的历程,以及在性能和复杂度之间的权衡考量。文章还介绍了Mutex的饥饿模式,通过该模式的引入,保证了请求锁的goroutine获取锁的公平性,避免了新来的goroutine一直抢占锁资源的情况。整体而言,本文对Mutex的演进历程和性能优化进行了深入剖析,为读者呈现了Go语言并发控制技术的精妙之处。文章内容丰富,深入浅出,是一篇值得深入阅读的技术文章。
《Go 并发编程实战课》,新⼈⾸单¥59
全部留言(106)
- 最新
- 精选
- Junes老师讲得太棒了,我自己看Mutex源码时,没有前因后果,知识不成体系。交个作业: 1. 目前 Mutex 的 state 字段有几个意义,这几个意义分别是由哪些字段表示的? 和第四个阶段的讲解基本一致:前三个bit分别为mutexLocked、mutexWoken、mutexStarving,剩余bit表示mutexWaiter 2. 等待一个 Mutex 的 goroutine 数最大是多少?是否能满足现实的需求? 单从程序来看,可以支持 1<<(32-3) -1 ,约 0.5 Billion个 其中32为state的类型int32,3位waiter字段的shift 考虑到实际goroutine初始化的空间为2K,0.5Billin*2K达到了1TB,单从内存空间来说已经要求极高了,当前的设计肯定可以满足了。
作者回复: 赞学习态度,赞作业
2020-10-147103 - buckwheat这源码看的感觉好难啊,尤其是这种并发的源码,老师有什么好的建议吗?
作者回复: Mutex和channel实现代码实现非常复杂,第一遍看不懂没关系,第二遍看不懂也没关系......,永远看不懂也不影响你使用它。你可以每次只尝试理解一个知识点。我的经验是多看几遍,每一个if分支都理解它的意思,在纸上画一画state的值的变化
2020-10-1437 - Dragon Frog老师,你好我有个疑问。在第二版中的 mutexWoken 这个含义到底该怎么理解。没办法很好的理解这个字段的作用
作者回复: 标记是否有“通过unlock唤醒”的waiter在竞争锁
2020-10-2513 - 锋老师您好,有个疑问。 runtime_Semrelease 信号唤起的总队queue中的第一个吗? 争抢锁在非饥饿模式下,是不是只有队首的waiter和新的goroutine之间发生? 谢谢
作者回复: 是的。你可以看runtime中的实现https://github.com/golang/go/blob/0a820007e70fdd038950f28254c6269cd9588c02/src/runtime/sema.go#L321
2020-10-1428 - 授人以🐟,不如授人以渔老师,有一个关于编程的疑惑,很难解决:我以后可能也会写一些复杂的逻辑,特别是并发的逻辑,但如何用逻辑思维去证明代码是没有问题的?比如第二版本的 Mutex 代码,就写的很好。
作者回复: 一点建议 一个是多学习并发的知识,充分了解并发的复杂性和场景。 二是实现并发原语的时候,要便利各种可能性
2021-11-034 - Leo看第一遍的时候真的一脸懵,所以想起了老师开篇讲的很重要的一句“先建立体系”,所以我第二遍没有去关注源码,而是去理解老师文档中对锁实现过程的描述找到大体脉络。也就是先理解思路,再去逐个追究源码的细节。所以第三遍就能很顺利理解Mutex第一个版本的实现,第二个版本因为涉及到位运算,所以需要先把go的位运算基础搞清楚再继续分析。虽然还没有完全弄懂整个Mutex的实现,但现在也收获良多,因为从源码以及老师的文档描述中包含了程序的策略,而这些策略也可以用于我们开发中解决其他问题。
作者回复: 👍🏻
2021-06-293 - 阿牛交作业 1、目前 Mutex 的 state 字段有几个意义,这几个意义分别是由哪些字段表示的? state有四个字段: • mutexLocked 占1bit,持有锁标记 • mutexWoken 占1bit,唤醒标记 • mutexStarving 占1bit,饥饿标记 • mutexWaiters 阻塞等待的waiter数量 2、等待一个 Mutex 的 goroutine 数最大是多少?是否能满足现实的需求? 32-3=29位=2^29=536 870 912
作者回复: 加油
2021-02-193 - 消逝文字底层实现的代码和业务代码果然有很大不同,理解起来也更加困难,光是上面那一堆位运算就已经够让人头疼的了,全程懵逼的看完了这一篇,还需要好好消化一下
作者回复: 没错,多来几遍,每次都有收获
2020-10-143 - Felix我有一件事想不明白,如果大家用的是同一个s ync.Mutex,那么在每个goroutine中的sema数值不都是一样的,如果其中一个goroutine中的mutexLocked变为1,所有goroutine中mutexLocked不都是变为1吗,我的理解是mutex没有用值传递,应该指向同一块内存区域啊。
作者回复: 对,所有的goroutine看到的都是一样的
2021-06-282 - 果酱new = old + 1<<mutexWaiterShift. 1<<mutexWaiterShift这个结果是4 为啥大佬注释说的是加1啊 求解
作者回复: waiter数从第4个bit开始
2020-11-2322