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/

https://blog.csdn.net/u011240016/article/details/53313422?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

https://www.cnblogs.com/lztkdr/p/8377853.html

https://blog.csdn.net/lamdoc/article/details/7662900?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

原文地址:https://www.cnblogs.com/lylhome/p/13428155.html