實現程序互斥的方法
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;