发布于2021-05-30 19:37 阅读(634) 评论(0) 点赞(29) 收藏(5)
state表示mutex的状态
上图是Mutex的结构体和locker接口方法定义
Mutex的公平性,两种操作模式 正常normal和饥饿starvation
- 互斥量可分为两种操作模式:正常和饥饿。
-
- 在正常模式下,等待的goroutines按照FIFO(先进先出)顺序排队,但是goroutine被唤醒之后并不能立即得到mutex锁,它需要与新到达的goroutine争夺mutex锁。
-
- 因为新到达的goroutine已经在CPU上运行了,所以被唤醒的goroutine很大概率是争夺mutex锁是失败的。出现这样的情况时候,被唤醒的goroutine需要排队在队列的前面。
-
- 如果被唤醒的goroutine有超过1ms没有获取到mutex锁,那么它就会变为饥饿模式。
-
- 在饥饿模式中,mutex锁直接从解锁的goroutine交给队列前面的goroutine。新达到的goroutine也不会去争夺mutex锁(即使没有锁,也不能去自旋),而是到等待队列尾部排队。
-
- 在饥饿模式下,有一个goroutine获取到mutex锁了,如果它满足下条件中的任意一个,mutex将会切换回去正常模式:
-
- 1. 是等待队列中的最后一个goroutine
-
- 2. 它的等待时间不超过1ms。
-
- 正常模式有更好的性能,因为goroutine可以连续多次获得mutex锁;
-
- 饥饿模式对于预防队列尾部goroutine一致无法获取mutex锁的问题。
下面看下核心方法lock
1.如果当前state为0,代表这个锁没有被持有,所以就通过CAS来获取锁,这个也是快速获取锁的路径
2.如果当前state不为0,那么就进行lockSlow流程
3.判断,如果是饥饿starvation模式,就不自旋,新到达的goroutine必须排队;如果是normal正常模式,就进入自旋,尝试获取锁
4.goroutine已经从sleep中唤醒,所以我们需要重置flag
6.获取锁成功,就直接break,如果之前已经等待过,就在queue的开头排队
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
下面再来看unlock释放锁
1.如果没有lock,直接就unlock,那么就会出现一个run-time 错误
2.一个锁住的mutex,不会专属于一个指定的goroutine;通常是一个goroutine锁住mutex,另一个goroutine争抢,来解锁unlock
3.快速解锁,就是state - mutexLocked,如果不为0,就调用unlockSlow解锁
4.如果没有waiters,或者1个goroutine已经被唤醒,并且抢到了锁,就没有必要唤醒其余的goroutine了
5.如果是饥饿模式,那么就直接解锁下一个waiter,新来的goroutine是需要在队尾排队的,就无法获取
作者:美丽的老婆你听我说
链接:http://www.phpheidong.com/blog/article/86837/9a931ae7bca01cd1268e/
来源:php黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 php黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-4
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!