进程互斥原则模板:
(1)互斥性
枚举所有情况,一个进程进入临界区后,另一个进程不能进入临界区
(2)进展性
枚举一个进程要求进入临界区后,能够进入临界区和多个进程要求进入临界区后,能有一个进入临界区
(3)有限等待性
一个进程离开临界区后,不会让该进程再度进入临界区,而是让其他进程也能够进入临界区
Dekker互斥算法
int flag[2];
int turn;
P0:do{
flag[0] = 1;
while flag[1] do
if(turn == 1){
flag[0] = 0;
while turn == 1 do
skip;
flag[0] = 1;
}
临界区
turn = 1;
flag[0] = 0;
其余代码
}while(1);
P1:do{
flag[1] = 1;
while flag[0] do{
if(turn == 0){
flag[1] = 0;
while turn == 0 do
skip;
flag[1] = 1;
}
}
临界区
turn = 0;
flag[1] = 0;
}while(1);
(1)考虑互斥性:
假设P0进入临界区,flag[0] = 1,P1欲进入临界区必定处于外层while循环忙式等待,满足互斥性
(2)考虑进展性:
若只有一个进程想进入临界区,假定为P0,则flag[1] = 0,P0结束外层while循环进入临界区。
若两个进程都想进入临界区,那么turn必定满足其中一个if条件,假设满足turn == 0,那么将flag[1]置为0,P1进入内层while循环忙式等待,而P0获得处理器资源后,由于flag[1] = 0,故退出外层while循环,进入临界区,满足进展性。
(3)考虑有限等待性:
假设P0处于临界区中,P1执行entry section代码试图进入临界区,P0离开临界区时,turn = 1,flag[0] = 0。
若在P1判断外层while循环之前,P0没有再次提出进入临界区,那么P1在外层while循环判断flag[0]条件不成立,进入临界区。
若在P1判断外层while循环之前,P0再次提出进入临界区,但此时turn = 1,P0会将flag[0]置为0进入忙式等待,直至P1进入并离开临界区。因而在P0再度进入临界区之前,必能获得进入临界区的机会,满足有限等待性。
Peterson互斥算法
int flag[2];
int turn;
P0:do{
flag[0] = 1;
turn = 1;
while flag[1] && turn == 1 do
skip;
临界区
flag[0] = 0;
其余代码
}while(1);
P1:do{
flag[1] = 1;
turn = 0;
while flag[0] && turn == 0 do
skip;
临界区
flag[1] = 0;
其余代码
}while(1);
(1)考虑互斥性:
假设P0进入临界区,此时分为三种情况
(a)flag[1]不满足 (b)turn == 1不满足 (c)二者均不满足
对于a,则说明此时P1还未请求进入临界区,若在之后P1请求进入临界区时,将turn赋值为0的操作后执行
对于b,则说明将turn赋值为0操作后执行
对于c,要求flag[1] = 0 且 turn = 0不可能实现,因为这要求P1未进入entry section而又将turn赋值为0。
可能的ab两种情况时,P0处于临界区,故flag[0] = 1,又turn = 0,因此P1将在while循环处执行忙式等待,满足互斥性。
(2)考虑进展性
若只有一个进程想进入临界区,假定为P0,flag[1] = 0,跳出while循环进入临界区
若两个进程都想进入临界区,只能满足turn = 0或turn =1两种情况,因此必定有一个结束while循环进入临界区,满足进展性。
(3)考虑有限等待性
若P0离开临界区,则flag[0] = 0
若在P1判断外层while循环之前,P0没有再次提出进入临界区,那么P1在外层while循环判断flag[0]条件不成立,进入临界区。
若在P1判断外层while循环之前,P0再次提出进入临界区,那么此时必定执行turn = 1, P0进入忙式等待,P1必定能进入临界区,满足有限等待性。
Lamport面包店算法
int choosing[n]; //choosing[i] = 1表示进程i正在抓号,否则为0
int number[i]; //number[i]为0表示进程i没有抓号,否则为正整数,初始为0
(1) (a,b) < (c,d) 如果 a < c or (a = c and b < d)成立
(2) max{a0,a1,...an-1}的值为一个正整数k,对于所有i(0 <= i <= n-1), k >= ai
do{
choosing[i] = 1;
number[i] = max{number[0],number[1],...,number[n-1]} + 1;
choosing[i] = 0;
for(j = 0; j < n; j++){
while(choosing[j])
skip;
while(number[j] != 0 && (number[j],j) < (number[i],i))
skip;
}
临界区
number[i] = 0;
其余代码
}while(1);
(1)考虑互斥性:
对于进程Pi,满足条件所抓号码为number[i],且对于其它想进入临界区的进程Pj有(number[i],i) < (number[j],j)。当Pi进入临界区后,其它进程将在第一个或第二个while处忙式等待,满足互斥性。
(2)考虑进展性:
当有多个进程竞争进入临界区时,有两种情况
(a)一个进程抓到最小号码 (b)若干个进程抓到最小号码
对于a,抓到最小号码的进程进入临界区
对于b,抓到最小号码且编号最小的进程进入临界区 因此满足进展性
(3)考虑有限等待性
因为竞争进程按照先进先出的次序进入临界区,而且进程数量有限,因此进程不会无限期地等待进入临界区,满足有限等待性。