硬件实现方法
之前的软件方法出现各种问题的根本原因其实是因为检查是否被占用和设置自己想要占用,这两个动作没有办法一气呵成导致的
而硬件实现的好处就是他的权限足够高,无法随意被中断
中断屏蔽方法
操作系统有一个系统级的指令是中断指令,主要分为两个步骤,一个是关中断指令,另一个是开中断指令
什么意思呢,就是说是否允许被中断,关中断就之后不允许被中断,开中断就是之后可以被中断
因此我们想要确保进程访问临界区时不被其他进程打扰,只需要在临界区之前执行关中断指令,在临界区之后执行开中断指令,确保进程互斥的实现
// 关中断;
// 临界区;
// 开中断;
这个方法的缺点是限制了CPU交替并发执行程序的能力,即便是时间片到也无法中断,因此系统的效率就会降低
其次这个方法其实是权限的下放,就是将系统的权限交给用户的进程,这样进程有可能会一直占用CPU
这个方法还无法限制其他CPU,只能限制一个CPU不执行相同临界区的代码
TestAndSet指令
这是一条硬件指令,TS指令,这条指令是原子操作,也就是原语,不允许被中断
他的代码描述如下
bool TestAndSet(bool* lock) // 交换逻辑
{
bool old = *lock; // old 存放旧的bool值
*lock = true; // 设置为true
return old; // 返回旧值
}
外面的代码如何进行调用呢,是这样的
while(TestAndSet(&lock)); // 进入区
// 临界区
lock = false; // 退出区
// 剩余区
这一段是多进程代码,也就是有两个进程都有相同的这一段,lock是全局变量,true表示临界资源被占用,初始值为false
当两个进程都不使用时,lock为false,执行到进入区时,另一个进程不允许再次进入执行,第一个进程检查并上锁后,第二个进程只能等待第一个进程执行完临界区代码
再次强调,这个硬件指令是由硬件指令实现的,并非代码
因此这个指令是一气呵成无法中断,其次这个方法的好处就是因为lock是全局变量,即便其他CPU想要访问也是同一个lock,也就无法抢占了
缺点就是没有解决让权等待的问题,因为while循环还是会一直占用CPU进行判断,除此之外也会导致饥饿现象
Swap指令
在上面的标注也提到了,其实这两个指令的软件逻辑是几乎一模一样的
因此优缺点也是相同的