OS 忙等待、让权等待、自旋锁、互斥锁的概念
在介绍临界区互斥问题的时候,提到了忙等待和让权等待的概念。
在解决临界区互斥问题的硬件解决方案中有一种利用TSL指令实现互斥的方案,里面提到了加锁的概念,查阅资料发现加锁有自旋锁和互斥锁两种。
首先,什么是忙等待?什么是让权等待?
忙等待:可以与自旋锁、轮询等同,进程不断申请进入临界区,直到被允许。像 while(judge)
让权等待:进程申请进入临界区,不被允许则睡眠(阻塞、等待)。像 sleep()
睡眠是阻塞的一种方式,睡眠的进程会sleep一段时间,醒来后继续运行。
两者比较,忙等待一直占用CPU,一直申请进入临界区操作,进程处于运行态;
让权等待申请一次后被拒,则主动让出CPU,进程处于阻塞态
那么,什么是自旋锁?什么是互斥锁?
锁:指进入临界区的判断标志,
比如变量LOCK,若LOCK=0,表示当前临界区无进程,申请的进程可以进入,若LOCK=1,表示当前临界区有进程,申请的进程都不允许进入
自旋锁:代码说明:while(LOCK==1); LOCK=1;(只是简单地说明意思,并不一定是这样的)
实际上,自旋锁是硬件实现的,会“锁总线”,将这两行代码变成一个原子操作(命令TSL或XCHG),以保证不会被中断,实现互斥。
互斥锁:代码说明:while(LOCK==1) {sleep; } LOCK=1;(只是简单地说明意思,并不一定是这样的)
同上,硬件实现,原子操作
两者比较,使用自旋锁会导致忙等待,使用互斥锁会导致进程让权等待
自旋锁的忙等会浪费CPU,长时间的浪费可能导致死锁。
所以,自旋锁适用于临界区操作时间短的多进程,操作时间短可以减少忙等的时间。
而互斥锁由于需要进程调度且睡眠时间较长,所以适用于临界区操作时间长的。
另外,自旋锁只适用于多处理器的情况,在单处理器中相当于空操作。why?
如果是单处理器,
对于非抢占式(没有时间片,只有结束或者阻塞的时候,才会释放CPU,让其他进程运行),
不会发生一个获得锁的进程被迫释放CPU的情况,所以进程会按照优先级完成临界区的操作,终止进程,让出CPU给下个进程。这种情况下,没有自旋的发生,自旋锁也就没用了。
对于抢占式(没有时间片,在运行过程中,会被高优先级的进程抢占CPU),
会发生一个获得锁的进程被抢占被迫释放CPU的情况,如果发生抢占,临界区的锁还在被抢占的进程手里,抢占CPU的进程没有获得锁,只能一直自旋,形成死锁。(所以自旋锁都设置了自旋时间的上限,以防止这种情况的发生)
为了应对抢占式可能形成死锁的情况,对自旋锁进行优化,使得单处理器的自旋锁可以禁止进程抢占,将抢占式变成非抢占式,而非抢占式又没有自旋,所以单处理器的自旋相当于空操作
参考
https://blog.csdn.net/liuchuo/article/details/51986201/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!