1软件方法:
1.1单标志法
/* PROCESS 0 */
while(turn != 0);
/* critical section */
turn = 1;
/* PROCESS 1 */
while(turn != 1);
/* critical section */
turn = 0;
特点:1)进入临界区之前先检查turn,如果等于进程号,就可以进入临界区,否则循环等待,因此可以实现互斥;2)等待期间会耗费处理器时间;3)两个进程交替使用处理器,执行速度取决于慢的进程;4)如果一个终止(无论是在临界区内还是临界区外),另一个会被永远阻塞。
1.2双标志先检查法
/* PROCESS 0 */
while(flag[1]);
flag[0] = true;
/* critical section */
flag[0] = false;
/* PROCESS 1 */
while(flag[0]);
flag[1] = true;
/* critical section */
flag[1] = false;
特点:1)进入临界区之前先检查另一个进程的flag,直到该flag==false,然后设置本进程的flag置为true,接着进入临界区,出了临界区再把本进程的flag置为false;2)如果一个进程出了临界区且置flag为false后终止,,则另一个进程不会被阻塞;3)如果一个进程在临界区内终止,或者在置flag为true且进入临界区之前终止,则另一个进程会永久阻塞;4)两个进程还可能同时进入临界区,导致互斥失败。
1.3双标志后检查法
/* PROCESS 0 */
flag[0] = true;
while(flag[1]);
/* critical section */
flag[0] = false;
/* PROCESS 1 */
flag[1] = true;
while(flag[0]);
/* critical section */
flag[1] = false;
特点:1)进入临界区之前先把本进程的flag置为true;然后再检查另一个进程的flag,直到该flag==false,接着进入临界区,出了临界区再把本进程的flag置为false;2)如果一个进程出了临界区且置flag为false后终止,则另一个进程不会被阻塞;3)如果一个进程在临界区内终止,或者在置flag为true之后且进入临界区之前终止,则另一个进程会永久阻塞;4)保证了互斥,但可能造成死锁。
1.4Dekker算法
void P0(){
while(true){
flag[0] = true;
while(flag[1]){
if(turn == 1){
flag[0] = false;
while(turn == 1);
flag[0] = true;
}
}
/* critical section */
turn = 1;
flag[0] = false;
}
}
void P1(){
while(true){
flag[1] = true;
while(flag[0]){
if(turn == 0){
flag[0] = false;
while(turn == 0);
flag[1] = true;
}
}
/* critical section */
turn = 0;
flag[1] = false;
}
}
特点:先置自己的flag为true,表明想要进入临界区的意愿,然后检查另一进程的flag,如果另一个进程也想进入临界区,则找第三方和事佬看一下turn——如果轮到其他进程,只能礼让,把自己的flag置为false,让另一个进程跳出循环进入临界区;如果轮到自己, 则等待对方把flag置为false,然后跳出循环进入临界区,出了临界区再把turn让给别人,同时置自己的flag为false。
1.5Peterson算法
void P0(){
while(true){
flag[0] = true;
turn = 1;
while(flag[1] && turn==1);
/* critical section */
flag[0] = false;
}
}
void P1(){
while(true){
flag[1] = true;
turn = 0;
while(flag[0] && turn==0);
/* critical section */
flag[1] = false;
}
}
特点: 先置自己的flag为true,表明想要进入临界区的意愿,但是先礼让其他进程,主动把turn让给其他人——如果其他进程刚好想进入临界区,上门的好事不要白不要,赶紧跳出循环进入临界区;如果其他进程不想进入临界区,则跳过循环进入临界区,出了临界区置自己的flag为false。
2硬件方法
2.1关中断
2.2TestAndSet指令
bool TestAndSet (bool &lock){
bool old;
old = lock;
lock = true;
return old;
}
while TestAndSet(&lock);
/* critical section */
lock = false;
exchange指令
void Swap (bool &a, bool &b){
bool temp;
temp = a;
a = b;
b = temp;
}
lock = false; //全局共享变量
key = true; //局部变量
while(key)
Swap(lock, key);
/* critical section */
lock = false;