一个标准的临界区处理办法要遵循下面这几点:
1、 任何两个进程不能同时处于临界区;
2、 临界区外运行的进程不得阻塞其他进程;
3、 不得使进程无限期等待进入临界区;
4、 不应对CPU的速度和数量做任何假设;
在处理临界区问题时,有忙等待的互斥处理办法,主要包括:
1)屏蔽中断;2)锁变量;3)严格轮换法;4)Peterson算法;5)TSL指令;
在看Peterson算法的时候,一直没能理解算法的精髓,有些思考和疑惑,记录一下,先展示算法:
代码中有两个变量,turn标示现在轮到进入临界区的进程号;interested[N]表示进程是否想要进入临界区。调用enter_region进入临界区,退出临界区时调用leave_region。调用enter_region传入当前进程号,设置本进程对临界区感兴趣interested[process]为true,turn变量设置为当前进程号。
假设现在有进程0和进程1,进程0想进入临界区,需要满足的条件有下面两种情况:
1、 turn==0:轮到0进程进入临界区
interested[0]==TRUE:进程0想进入临界区
interested[1]==FALSE:进程1不想进入临界区
2、 turn==1:进程0和进程1都想进入临界区,当进程0改写完turn值后,turn值被进程1覆盖
interested[0]==TRUE:进程0想进入临界区
interested[1]==TRUE:进程1想进入临界区
从开头的几个原则来分析这个算法:
- 任何两个进程不能同时在临界区
由上面代码分析可知,进入临界区的条件由turn和interested[other]的值决定:
当turn==process时,如果interested[other]==FALSE,表示other进程不在临界区,process可以进入;如果interested[other]==TRUE,表示other进程在临界区内,或者other进程也调用enter_region且执行到interested[process]==TRUE和turn=process之间,这两种情况process都要被阻塞。
当turn!=process时,根据代码执行顺序,在while之前肯定会执行turn=process,所以出现这种情况只有一种可能,就是process进程执行完turn=process后,other进程也执行了turn=process,导致turn被other进程篡改,这时interested[other]==TRUE,process进程可以进入临界区,other进程阻塞。
- 临界区外运行的进程不得阻塞其他进程
关于这一点,有些疑惑,考虑下面这种情况:当turn==process,且interested[other]==TRUE时,process进程被阻塞,如果other进程执行到interested[process]==TRUE和turn=process之间时发生中断,other进程阻塞执行,那么process进程会被在临界区外的other进程阻塞。
- 不得使进程无限期等待进入临界区
同上,如果other被中断,则process有被无限阻塞的风险。
- 不应对CPU的速度和数量做任何假设