1. 程式人生 > >實現程序互斥的方法

實現程序互斥的方法

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;