【Peterson 算法】
它是一种基于软件的,可以解决两个进程处于临界区的时候的问题的算法。
当进程并发执行访问临界资源时,它通过使用两个共享变量来确保互斥、前进和有限等待条件,从而防止进程陷入无限循环而无法访问到需要的资源。
两个共享变量为:
一个是事件flag,
一个是开关turn
进程P0和P1的共享变量定义及其初值为:
boolean flag[2];
int turn=0;
flag[0]=FALSE;flag[1]=FALSE;
若进行P0和P1访问临界资源的代码实现如下:
void P0() //进程P0
{while(TRUE){flag[0]=TRUE;turn=1;while(flag[1]&&(turn==1));临界区;flag[0]=FALSE; }
}
void P1() //进程P1
{while(TRUE){flag[1]=TRUE;turn=0;while(flag[0]&&(turn==0));临界区;flag[1]=FALSE; }
}
则并发执行进程P0和P1时产生的情形是( )
A.不能保证进程互斥进入临界区,会出现“饥饿”现象
B.不能保证进程互斥进入临界区,不会出现“饥饿”现象
C.能保证进程互斥进入临界区,会出现“饥饿”现象
D.能保证进程互斥进入临界区,不会出现“饥饿”现象
在这里说一下我的理解,可以写在表格上来表示更加地直观,欢迎多多指教:
进程P0 | 进程P1 | |||
第 一 步 | flag[0]=TRUE; turn=1; 进程P0进场, 开启事件flag[0], 开启turn开关 | 此时进程P0与进程P1同时进行 | 第一步 | flag[1]=TRUE; turn=0; 进程P1进场, 开启事件flag[1], 关闭turn开关 |
第 二 步 | while(flag[1]&&(turn==1)); 此时的进程P0获取事件flag[1]的值为TRUE, 同时进程P0获取turn的值为1, 所以进程P0在这里开始进入循环等待。 | 第二步 | while(flag[0]&&(turn==0)); 这里的进程P1第二步与进程P0的第二步是同步进行的,也就是进程P1和进程P0此时都处于第二步, 此时进程P1获取事件flag[0]的值为TRUE,同时进程P1获取turn的值为0,那么就符合循环条件, 所以进程P1从这里也开始进入循环等待。 | |
那么现在的状况就是: ------------------------------------------------------------------------------------------- 你看到没有,这代码是从上写到下的,虽说进程同步进行,所以肯定进程P0要比进程P1先一点点 ------------------------------------------------------------------------------------------- 故而 进程P0开始进入循环等待,想让进程P1先进入临界区, 进程P1也随后开始进入循环等待,想让进程P0也进入临界区, ------------------------------------------------------------------------------------------- 但现在系统吃到的turn的值为0, 所以在系统吃到的turn的值为0之后,进程P0也就跳出了循环等待,“我不等了!!!” 于是进程P0进入临界区,进行访问临界资源的工作,访问完临界资源后,退出临界区,用第三步flag[0]=FALSE;将事件flag[0]关闭 ------------------------------------------------------------------------------------------- 那么此时事件flag[0]已经关闭了,于是进程P1也不再满足循环条件随后跳出了循环等待,“终于轮到我了!!!” 于是进程P1也进入临界区,进行访问临界资源的工作,访问完临界资源后,退出临界区,用第三步flag[1]=FALSE;将事件flag[1]关闭 | ||||
第三步 | flag[0]=FALSE; 进程P0在这个时候将事件flag[0]关闭 | 第三步 | flag[1]=FALSE; 进程P1在这个时候将事件flag[1]关闭 | |
那么现在的状况就是: flag[0]=FALSE; 也就是事件flag[0]现已关闭 flag[1]=FALSE; 也就是事件flag[1]现已关闭 turn=0; 也就是系统最后吃到的turn值为0 | ||||
【进程饥饿】 是操作系统中的进程在并发环境下,因资源分配策略不公导致其他进程持续占用所需资源,而特定进程无法在可预期的时间阈值内执行并获得必需资源,此时该进程的这种运行状态便为"饥饿死亡"状态,即此时的进程即使获得资源也无法有效完成任务。 | ||||
所以总结一下: 题中的代码用到了Peterson算法,通过使用两个共享变量即事件flag【包含事件flag[0]和事件flag[1]】、开关turn这两个来能保证进程互斥进入临界区,所以并发执行进程P0和P1时产生的情形是
故整个流程完成后,我们可以看出使用Peterson算法后,并发执行的进程不会出现【在可预期的时间阈值内其他进程持续占用所需资源,特定进程无法进行执行并获得必需资源】的运行状态,也就是不会出现“饥饿”现象。 |