进程互斥原则模板:
(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)考虑有限等待性
因为竞争进程按照先进先出的次序进入临界区,而且进程数量有限,因此进程不会无限期地等待进入临界区,满足有限等待性。