Dekkel互斥算法
flag表示是否想进入临界区,turn表示轮到谁
int flag[2]; (init 0)
int turn; (0 or 1)
P0:
do{
flag[0]=1;
while(flag[1])
if(turn==1){
flag[0]=0;
while (turn==1)
skip;
flag[0]=1;
}
临界区
turn=1;
flag[0]=0;
其余代码
}while(1);
P1:
do{
flag[1]=1;
while(flag[0])
if(turn==0){
flag[1]=0;
while (turn==0)
skip;
flag[1]=1;
}
临界区
turn=0;
flag[1]=0;
其余代码
}while(1);
分析:
以p0为例,将p0的flag设为1,表示p0想进入临界区;即使p0宣布自己想进入临界区,但是p1也可能想进入临界区,于是进入while循环:
如果turn=1,说明现在轮到p1,将p0的flag设置为0,谦让给p1进程,p0等待,直到turn=0,将p0的flag再次设置为1,注意要再次回到while(flag[1])看flag[1]是否变为0(即p1是否退出临界区),如果为0则p0进程访问临界区,否则继续循环
该算法与Peterson很相似
Eisenberg-Mcguire算法
enum flag[0,…,n-1] (idle, want_in, in_cs);
int turn; //0…n-1; 初始任意
flag[i]==idle: //进程Pi不想进入临界区
flag[i]==want_in: //进程Pi想进入临界区
flag[i]==in_cs: //进程Pi想进入或已进入临界区
分析:
while(j!=i){
if(flag[j]!=idle){
j = trun; //j想要访问/已经访问临界资源,此时i进程就等待
}
else{
j = (j+1)%n; //往后循环遍历,慢慢循环总会轮到自己
}
}
对于跳出while循环的语句的解释
在不断循环中,直到这个序列除了自己以外都不是in_cs(即循环后j>=n)
要么轮到我自己去拿资源(即turn==i) 要么是轮到别人执行的执行完了(即flag[turn]==idle) 那么我都可以访问临界区