操作系統——哲學家進餐問題的解決方法


問題描述

五個哲學家共用一張圓桌,分別坐在五張椅子上,圓桌上有五個碗和五只筷子。平時哲學家進行思考,當即飢餓時拿起左右兩邊的筷子,只有拿到兩只筷子時才能進餐,進餐完畢,放下筷子繼續思考。

問題分析

這是經典的進程同步問題。筷子是臨界資源,每只筷子都用一個互斥量表示。
semaphore chopstick[5] = {1, 1, 1, 1, 1}
錯誤示例:

semaphore chopstick[5] = {1, 1, 1, 1, 1};
void philosopher(int i){
    do{
        wait(chopstick[i]);
        wait(chopstick[(i+1)%5]);
        //eat
        //...
        signal(chopstick[i]);
        signal(chopstick[(i+1)%5]);
        
        //think
        //...
    }while(true);
}

這樣做會帶來一個問題,當五個哲學家同時飢餓拿起左邊的筷子時,試圖拿右邊的筷子,就會進入死鎖。

解決方法

1.至多有四位哲學家同時拿起左邊的筷子,即至多只有四個哲學家同時進餐,這樣能保證至少有一個哲學家能夠進餐。
2.僅當哲學家左右兩邊的筷子都可用時,才能進餐
3.規定奇數號哲學家先拿左邊的筷子,再拿右邊的筷子;偶數號哲學家相反。

解法1

用一個信號量counter表示哲學家同時進餐的人數,初始值為4

semaphore chopstick[5] = {1, 1, 1, 1, 1};
counter=4;
void philosopher(int i){
    do{
        wait(counter);
        wait(chopstick[i]);
        wait(chopstick[(i+1)%5]);
        //eat
        //...
        signal(chopstick[i]);
        signal(chopstick[(i+1)%5]);
        signal(counter)
        //think
        //...
    }while(true);
}

解法2

使用AND型信號量,當兩個臨界資源都滿足后才能進餐

semaphore chopstick[5] = {1, 1, 1, 1, 1};
void philosopher(int i){
    do{
        Swait(chopstick[i], chopstick[(i+1)%5]);
        //eat
        //...
        Ssignal(chopstick[i], chopstick[(i+1)%5]);
        //think
        //...
    }while(true);
}

解法3

semaphore chopstick[5] = {1, 1, 1, 1, 1};
void philosopher(int i){
    do{
        if(i%2){
            wait(chopstick[i]);
            wait(chopstick[(i+1)%5]);
        }
        else{
            wait(chopstick[(i+1)%5]);
            wait(chopstick[i]);
        }
        //eat
        //...
        signal(chopstick[i]);
        signal(chopstick[(i+1)%5]);
        //think
        //...
    }while(true);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM