在说明之前我先抛出结论: 互斥锁和二值信号量在使用上非常相似, 但是互斥锁解决了优先级翻转的问题
假定我们现在有三个任务, task1,task2,task3, 任务优先级 task1 最高, 然后依次降低. 我们知道在系统调度的时候当两个任务同时处于就绪态的时候, 系统会优先执行优先级高的任务
好了, 让我们来看两个案例
优先级翻转分析 (使用信号量)
在例子中, 我们使用 pend() 函数来表示获取信号量, 用 post() 函数来表示释放信号量
如上图所示, 过程分下面几步
1. 一开始 task3 开始运行, 先获取到信号量
2.task1 开始运行尝试去获取信号量失败被阻塞等待 task3 执行完
3.task3 运行过程中, task2 被触发, 由于其优先级高于 task3,task2 被运行, 浪费了大量时间
4. 继续运行 task3, 运行完后释放信号量
5.task1 继续运行
看到这里我们可以得知, 本应该优先级最高的 task1 结果居然是最后开始运行的, 这就是优先级反转现象. 这明显是不利的. 比如如果有安装看门狗, task1 在长时间没有得到执行, 就会触发看门狗, 导致系统的重启.
改进分析 (使用互斥锁)
在例子中, 我们使用 lock() 函数来表示获取互斥锁, 用 unlock() 函数来表示释放互斥锁
如上图所示, 过程分下面几步
1. 一开始 task3 开始运行, 先获取到互斥锁
2.task1 开始运行尝试去获取互斥锁失败被阻塞等待 task3 执行完, 但是此时提升 task3 的优先级, 让其优先级跟自己一样
3.task3 运行过程中, task2 被触发, 由于其优先级低于 task3(第 2 步被提升过),task2 等待运行
4. 继续运行 task3, 运行完后释放互斥锁
5.task1 继续运行
6.task1 执行完, 执行 task2
所以过程跟前面的虽然一样, 但是互斥锁多做了一个步骤就是将 task3 的优先级提升到 task1 的级别, 防止 task2 中途出来搅局浪费大量时间.
生活中的实例类比
使用信号量的情况:
领导在台上讲话. 场内三个角色, 领导, 组长, 小兵.
小兵先拿起话筒说话, 领导要讲话发现没有话筒, 就等待小兵讲完.
组长要讲话, 由于他比较野蛮, 不需要话筒, 并制止了小兵说话, 自己开始说.
组长讲完, 小兵接着讲
小兵讲完, 把话筒给领导, 领导讲完
使用互斥锁的情况:
领导在台上讲话. 场内三个角色, 领导, 组长, 小兵.
小兵先拿起话筒说话, 领导要讲话发现没有话筒, 就等待小兵讲完, 并且跟小兵说, 现在你就是领导的身份
组长要讲话, 但是他发现领导已经赋予了小兵比自己更高的权限, 自己没有权力打断, 只好作罢
小兵讲完, 把话筒给领导, 领导讲完
这时候组长才开始讲话
以上是个人对二值信号量和互斥锁区别的理解, 初入职场. 对于知识的把握难免会有所不足, 欢迎各位大佬批评指正
来源: https://www.cnblogs.com/codescrew/p/8970514.html