當前位置:首頁 » 操作系統 » 飢餓演算法

飢餓演算法

發布時間: 2023-08-22 21:34:46

❶ 麵包店演算法的優缺點

優點:進程之間並行,有界共享寄存器。缺點:多進程讀/寫原子操作寄存器;飢餓問題,無容錯性(沒有等待資源釋放)。lamport演算法又稱為麵包店演算法,它解決了多個線程並發訪問一個共享的單用戶資源的互斥問題的演算法。優點:進程之間並行,有界共享寄存器。缺點:多進程姿寬讀/寫原子操作寄存器;飢餓問題,無容錯性(沒有等滑冊碰待資源釋放)。麵包信談店演算法借鑒生活中取號排隊的思想,取得的號不為0,則表示想要進去,按號碼從小到大授予訪問許可權。

❷ 哲學家就餐問題的演算法實現

操作系統並發和互斥:哲學家進餐問題和理發師問題

1. 哲學家進餐問題:
(1) 在什麼情況下5 個哲學家全部吃不上飯?
考慮兩種實現的方式,如下:
A.
演算法描述:
void philosopher(int i) /*i:哲學家編號,從0 到4*/
{
while (TRUE) {
think( ); /*哲學家正在思考*/
take_fork(i); /*取左側的筷子*/
take_fork((i+1) % N); /*取左側筷子;%為取模運算*/
eat( ); /*吃飯*/
put_fork(i); /*把左側筷子放回桌子*/
put_fork((i+1) % N); /*把右側筷子放回桌子*/
}
}
分析:假如所有的哲學家都同時拿起左側筷子,看到右側筷子不可用,又都放下左側筷子,
等一會兒,又同時拿起左側筷子,如此這般,永遠重復。對於這種情況,即所有的程序都在
無限期地運行,但是都無法取得任何進展,即出現飢餓,所有哲學家都吃不上飯。
B.
演算法描述:
規定在拿到左側的筷子後,先檢查右面的筷子是否可用。如果不可用,則先放下左側筷子,
等一段時間再重復整個過程。
分析:當出現以下情形,在某一個瞬間,所有的哲學家都同時啟動這個演算法,拿起左側的筷
子,而看到右側筷子不可用,又都放下左側筷子,等一會兒,又同時拿起左側筷子……如此
這樣永遠重復下去。對於這種情況,所有的程序都在運行,但卻無法取得進展,即出現飢餓,
所有的哲學家都吃不上飯。
(2) 描述一種沒有人餓死(永遠拿不到筷子)演算法。
考慮了四種實現的方式(A、B、C、D):
A.原理:至多隻允許四個哲學家同時進餐,以保證至少有一個哲學家能夠進餐,最終總會釋
放出他所使用過的兩支筷子,從而可使更多的哲學家進餐。以下將room 作為信號量,只允
許4 個哲學家同時進入餐廳就餐,這樣就能保證至少有一個哲學家可以就餐,而申請進入
餐廳的哲學家進入room 的等待隊列,根據FIFO 的原則,總會進入到餐廳就餐,因此不會
出現餓死和死鎖的現象。
偽碼:
semaphore chopstick[5]={1,1,1,1,1};
semaphore room=4;
void philosopher(int i)
{
while(true)
{
think();
wait(room); //請求進入房間進餐
wait(chopstick[i]); //請求左手邊的筷子
wait(chopstick[(i+1)%5]); //請求右手邊的筷子
eat();
signal(chopstick[(i+1)%5]); //釋放右手邊的筷子
signal(chopstick[i]); //釋放左手邊的筷子
signal(room); //退出房間釋放信號量room
}
}
B.原理:僅當哲學家的左右兩支筷子都可用時,才允許他拿起筷子進餐。
方法1:利用AND 型信號量機制實現:根據課程講述,在一個原語中,將一段代碼同時需
要的多個臨界資源,要麼全部分配給它,要麼一個都不分配,因此不會出現死鎖的情形。當
某些資源不夠時阻塞調用進程;由於等待隊列的存在,使得對資源的請求滿足FIFO 的要求,
因此不會出現飢餓的情形。
偽碼:
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int I)
{
while(true)
{
think();
Swait(chopstick[(I+1)]%5,chopstick[I]);
eat();
Ssignal(chopstick[(I+1)]%5,chopstick[I]);
}
}
方法2:利用信號量的保護機制實現。通過信號量mutex對eat()之前的取左側和右側筷
子的操作進行保護,使之成為一個原子操作,這樣可以防止死鎖的出現。
偽碼:
semaphore mutex = 1 ;
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int I)
{
while(true)
{
think();
wait(mutex);
wait(chopstick[(I+1)]%5);
wait(chopstick[I]);
signal(mutex);
eat();
signal(chopstick[(I+1)]%5);
signal(chopstick[I]);
}
}
C. 原理:規定奇數號的哲學家先拿起他左邊的筷子,然後再去拿他右邊的筷子;而偶數號
的哲學家則相反.按此規定,將是1,2號哲學家競爭1號筷子,3,4號哲學家競爭3號筷子.即
五個哲學家都競爭奇數號筷子,獲得後,再去競爭偶數號筷子,最後總會有一個哲學家能獲
得兩支筷子而進餐。而申請不到的哲學家進入阻塞等待隊列,根FIFO原則,則先申請的哲
學家會較先可以吃飯,因此不會出現餓死的哲學家。
偽碼:
semaphore chopstick[5]={1,1,1,1,1};
void philosopher(int i)
{
while(true)
{
think();
if(i%2 == 0) //偶數哲學家,先右後左。
{
wait (chopstick[ i + 1 ] mod 5) ;
wait (chopstick[ i]) ;
eat();
signal (chopstick[ i + 1 ] mod 5) ;
signal (chopstick[ i]) ;
}
Else //奇數哲學家,先左後右。
{
wait (chopstick[ i]) ;
wait (chopstick[ i + 1 ] mod 5) ;
eat();
signal (chopstick[ i]) ;
signal (chopstick[ i + 1 ] mod 5) ;
}
}
D.利用管程機制實現(最終該實現是失敗的,見以下分析):
原理:不是對每隻筷子設置信號量,而是對每個哲學家設置信號量。test()函數有以下作
用:
a. 如果當前處理的哲學家處於飢餓狀態且兩側哲學家不在吃飯狀態,則當前哲學家通過
test()函數試圖進入吃飯狀態。
b. 如果通過test()進入吃飯狀態不成功,那麼當前哲學家就在該信號量阻塞等待,直到
其他的哲學家進程通過test()將該哲學家的狀態設置為EATING。
c. 當一個哲學家進程調用put_forks()放下筷子的時候,會通過test()測試它的鄰居,
如果鄰居處於飢餓狀態,且該鄰居的鄰居不在吃飯狀態,則該鄰居進入吃飯狀態。
由上所述,該演算法不會出現死鎖,因為一個哲學家只有在兩個鄰座都不在進餐時,才允
許轉換到進餐狀態。
該演算法會出現某個哲學家適終無法吃飯的情況,即當該哲學家的左右兩個哲學家交替
處在吃飯的狀態的時候,則該哲學家始終無法進入吃飯的狀態,因此不滿足題目的要求。
但是該演算法能夠實現對於任意多位哲學家的情況都能獲得最大的並行度,因此具有重要
的意義。
偽碼:
#define N 5 /* 哲學家人數*/
#define LEFT (i-1+N)%N /* i的左鄰號碼 */
#define RIGHT (i+1)%N /* i的右鄰號碼 */
typedef enum { THINKING, HUNGRY, EATING } phil_state; /*哲學家狀態*/
monitor dp /*管程*/
{
phil_state state[N];
semaphore mutex =1;
semaphore s[N]; /*每個哲學家一個信號量,初始值為0*/
void test(int i)
{
if ( state[i] == HUNGRY &&state[LEFT(i)] != EATING &&
state[RIGHT(i)] != EATING )
{
state[i] = EATING;
V(s[i]);
}
}
void get_forks(int i)
{
P(mutex);
state[i] = HUNGRY;
test(i); /*試圖得到兩支筷子*/
V(mutex);
P(s[i]); /*得不到筷子則阻塞*/
}
void put_forks(int i)
{
P(mutex);
state[i]= THINKING;
test(LEFT(i)); /*看左鄰是否進餐*/
test(RIGHT(i)); /*看右鄰是否進餐*/
V(mutex);
}
}
哲學家進程如下:
void philosopher(int process)
{
while(true)
{
think();
get_forks(process);
eat();
put_forks(process);
}
}
2.理發師問題:一個理發店有一個入口和一個出口。理發店內有一個可站5 位顧客的站席
區、4 個單人沙發、3 個理發師及其專用理發工具、一個收銀台。新來的顧客坐在沙發上等
待;沒有空沙發時,可在站席區等待;站席區滿時,只能在入口外等待。理發師可從事理
發、收銀和休息三種活動。理發店的活動滿足下列條件:
1)休息的理發師是坐地自己專用的理發椅上,不會佔用顧客的沙發;
2)處理休息狀態的理發師可為在沙發上等待時間最長的顧客理發;
3)理發時間長短由理發師決定;
4)在站席區等待時間最長的顧客可坐到空閑的理發上;
5)任何時刻最多隻能有一個理發師在收銀。
試用信號量機制或管程機制實現理發師進程和顧客進程。
原理:
(1)customer 進程:
首先檢查站席區是否已滿(stand_capacity),若滿選擇離開,否則進入站席區,即進入
理發店。在站席區等待沙發的空位(信號量sofa),如果沙發已滿,則進入阻塞等待隊列,
直到出現空位,在站席區中等待時間最長的顧客離開站席區(stand_capacity)。坐到沙
發上,等待理發椅(barber_chair),如果理發椅已滿,則進入阻塞等待隊列,直到出現
空位,在沙發上等待時間最長的顧客離開沙發(釋放信號量sofa)。坐到理發椅上,釋放
准備好的信號(customer_ready),獲得該理發師的編號(0~1 的數字)。等待理發師理
發結束(finished[barber_number])。在離開理發椅之前付款(payment),等待收據
(receipt),離開理發椅(leave_barberchair)。最後離開理發店。
這里需要注意幾點:
a) 首先是幾個需要進行互斥處理的地方,主要包括:進入站席區、進入沙發、進入理發椅
和付款幾個地方。
b) 通過barber_chair 保證一個理發椅上最多隻有一名顧客。但這也不夠,因為單憑
baber_chair 無法保證一名顧客離開理發椅之前,另一位顧客不會坐到該理發椅上,
因此增加信號量leave_barberchair,讓顧客離開理發椅後,釋放該信號,而理發
師接收到該信號後才釋放barber_chair 等待下一位顧客。
c) 在理發的過程中,需要保證是自己理發完畢,才能夠進行下面的付款、離開理發椅的活
動。這個機制是通過customer 進程獲得給他理發的理發師編號來實現的,這樣,當
該編號的理發師釋放對應的finished[i]信號的時候,該顧客才理發完畢。
d) 理發師是通過mutex 信號量保證他們每個人同時只進行一項操作(理發或者收款)。
e) 為了保證該顧客理發完畢後馬上可以付款離開,就應該保證給該顧客理發的理發師在理
發完畢後馬上到收銀台進入收款操作而不是給下一位顧客服務。在偽碼中由以下機制實
現:即顧客在釋放離開理發椅的信號前,發出付款的信號。這樣該理發師得不到顧客的
離開理發椅的信號,不能進入下一個循環為下一名顧客服務,而只能進入收款台的收款
操作。直到顧客接到收據後,才釋放離開理發椅的信號,離開理發椅,讓理發師釋放該
理發椅的信號,讓下一位等待的顧客坐到理發椅上。
(2)barber 進程
首先將該理發師的編號壓入隊列,供顧客提取。等待顧客坐到理發椅坐好(信號量
customer_ready),開始理發,理發結束後釋放結束信號(finished[i])。等待顧客
離開理發椅(leave_barberchair)(期間去收銀台進行收款活動),釋放理發椅空閑信
號(barber_chair),等待下一位顧客坐上來。
(3)cash(收銀台)進程
等待顧客付款(payment),執行收款操作,收款操作結束,給付收據(receipt)。
信號量總表:
信號量 wait signal
stand_capacity 顧客等待進入理發店 顧客離開站席區
sofa 顧客等待坐到沙發 顧客離開沙發
barber_chair 顧客等待空理發椅 理發師釋放空理發椅
customer_ready 理發師等待,直到一個顧客坐
到理發椅
顧客坐到理發椅上,給理發師
發出信號
mutex 等待理發師空閑,執行理發或
收款操作
理發師執行理發或收款結束,
進入空閑狀態
mutex1 執行入隊或出隊等待 入隊或出隊結束,釋放信號
finished[i] 顧客等待對應編號理發師理
發結束
理發師理發結束,釋放信號
leave_barberchair 理發師等待顧客離開理發椅 顧客付款完畢得到收據,離開
理發椅釋放信號
payment 收銀員等待顧客付款 顧客付款,發出信號
receipt 顧客等待收銀員收、開具收據收銀員收款結束、開具收據,
釋放信號
偽碼:
semaphore stand_capacity=5;
semaphore sofa=4;
semaphore barber_chair=3;
semaphore customer_ready=0;
semaphore mutex=3;
semaphore mutex1=1;
semaphore finished[3]={0,0,0};
semaphore leave_barberchair=0;
semaphore payment=0;
semaphore receipt=0;
void customer()
{
int barber_number;
wait(stand_capacity); //等待進入理發店
enter_room(); //進入理發店
wait(sofa); //等待沙發
leave_stand_section(); //離開站席區
signal(stand_capacity);
sit_on_sofa(); //坐在沙發上
wait(barber_chair); //等待理發椅
get_up_sofa(); //離開沙發
signal(sofa);
wait(mutex1);
sit_on_barberchair(); //坐到理發椅上
signal(customer_ready);
barber_number=dequeue(); //得到理發師編號
signal(mutex1);
wait(finished[barber_number]); //等待理發結束
pay(); //付款
signal(payment); //付款
wait(receipt); //等待收據
get_up_barberchair(); //離開理發椅
signal(leave_barberchair); //發出離開理發椅信號
exit_shop(); //了離開理發店
}
void barber(int i)
{
while(true)
{
wait(mutex1);
enqueue(i); //將該理發師的編號加入隊列
signal(mutex1);
wait(customer_ready); //等待顧客准備好
wait(mutex);
cut_hair(); //理發
signal(mutex);
signal(finished[i]); //理發結束
wait(leave_barberchair); //等待顧客離開理發椅信號
signal(barber_chair); //釋放barber_chair 信號
}
}
void cash() //收銀
{
while(true)
{
wait(payment); //等待顧客付款
wait(mutex); //原子操作
get_pay(); //接受付款
give_receipt(); //給顧客收據
signal(mutex);
signal(receipt); //收銀完畢,釋放信號
}
}
分析:
在分析該問題過程中,出現若干問題,是參閱相關資料後才認識到這些問題的隱蔽性和嚴重
性的,主要包括:
(1)在顧客進程,如果是在釋放leave_barberchair 信號之後進行付款動作的話,很
容易造成沒有收銀員為其收款的情形, 原因是: 為該顧客理發的理發師收到
leave_barberchair 信號後,釋放barber_chair 信號,另外一名顧客坐到理發椅上,
該理發師有可能為這另外一名顧客理發,而沒有為剛理完發的顧客收款。為解決這個問題,
就是採取在釋放leave_barberchair 信號之前,完成付款操作。這樣該理發師無法進入
下一輪循環為另外顧客服務,只能到收銀台收款。
(2)本演算法是通過給理發師編號的方式,當顧客坐到某理發椅上也同時獲得理發師的編號,
如此,當該理發師理發結束,釋放信號,顧客只有接收到為其理發的理發師的理發結束信號
才會進行付款等操作。這樣實現,是為避免這樣的錯誤,即:如果僅用一個finished 信
號量的話,很容易出現別的理發師理發完畢釋放了finished 信號,把正在理發的這位顧
客趕去付款,而已經理完發的顧客卻被阻塞在理發椅上的情形。當然也可以為顧客進行編
號,讓理發師獲取他理發的顧客的編號,但這樣就會限制顧客的數量,因為finished[]
數組不能是無限的。而為理發師編號,則只需要三個元素即可。
3.參考文獻:
左金平 計算機操作系統中哲學家進餐問題探究。
參考教材 操作系統—內核與設計原理

❸ 哪種調度演算法會導致飢餓

一、處理機調度相關基本概念
1、調度方式和調度演算法的若干准則
1)面向用戶的准則:周轉時間短(CPU執行用時Ts、周轉時間T=Ts+Tw、帶權周轉時間W= T/Ts)、響應時間快、均衡性、截止時間的保證、優先權准則
2)面向系統的准則:系統吞吐量高、處理機利用率好、各類資源的平衡利用
3)批處理系統為照顧為數眾多的短作業,應採用短作業優先的調度演算法;分時系統為保證系統具有合理的響應時間,應採用輪轉法進行調度
二、常用調度演算法
1、先來先服務調度演算法FCFS
(1)按照作業提交,或進程變為就緒狀態的先後次序分派CPU;
(2)新作業只有當當前作業或進程執行完或阻塞才獲得CPU運行
(3)被喚醒的作業或進程不立即恢復執行,通常等到當前作業或進程出讓CPU。(所以,默認即是非搶占方式)
(4)有利於CPU繁忙型的作業,而不利於I/O繁忙的作業(進程)。

2、短作業(進程)優先調度演算法SJF(非搶占)/SPF(搶占)
(1)平均周轉時間、平均帶權周轉時間都有明顯改善。SJF/SPF調度演算法能有效的降低作業的平均等待時間,提高系統吞吐量。
(2)未考慮作業的緊迫程度,因而不能保證緊迫性作業(進程)的及時處理、對長作業的不利、作業(進程)的長短含主觀因素,不一定能真正做到短作業優先。

3、高優先權優先調度演算法HPF
(1)兩種方式:非搶占式優先權演算法、搶占式優先權演算法(關鍵點:新作業產生時)
(2)類型:靜態優先權:創建進程時確定,整個運行期間保持不變。動態優先權:創建進程時賦予的優先權可隨進程的推進或隨其等待時間的增加而改變。
(3)高響應比優先調度演算法HRRN
HRRN為每個作業引入動態優先權,使作業的優先順序隨著等待時間的增加而以速率a提高:優先權 =(等待時間+要求服務時間)/要求服務時間= 響應時間 / 要求服務時間。
什麼時候計算各進程的響應比優先權?(作業完成時、新作業產生時(搶占、非搶占)、時間片完成時、進程阻塞時)

❹ 操作系統處理機典型調度演算法

1.先來先服務演算法
作業調度、進程調度
先來的先分配處理機
優點:演算法簡單,對長作業有利,有利於CPU繁忙型作業(計算型)
缺點:效率低,不利於短作業,不利於IO繁忙型作業
不會導致飢餓
非搶占型的演算法

2.短作業優先演算法
進程調度
優先選擇預計運行時間最短的進程
優點:平均等待時間、平均周轉時間短
缺點:對長作業不利,造成飢餓現象,沒有考慮作業的緊迫性,用戶可能縮短作業預估時間,使得無法做到短作業優先
產生「飢餓」現象。如果一直得不到服務,則稱為「餓死」
SJF和SPF(短進程優先(SPF)演算法)是非搶占式的演算法。但是也有搶占式的版本——最短剩餘時間優先算雹激拍法

3.優先順序調度演算法
作業調度、進程調度

分類:
剝奪型:立即停止當前運行進程,將處理機分配給更高優先順序進程
非剝奪型:等待當前進程運行完成,然後將處理機分配給更高優先順序進程

優先順序分配:
靜態優先順序:進程創建後無法對優先順序進行修改
動態優先順序:可以根據進程運行狀態,對進程優先順序進行動態調整

優先順序設置原則:
系統進程>用戶進程
交互性進程>非交互性進程
I/O進程>計算型進程(CPU繁忙型)

產生「飢餓」現象
有搶占式的,也有非搶占式的

4.高響應比調度演算法
響應比=(等待時間+要求服務時間)/要求服務時間=1+等待時間/要求服務時間
等待時間相同情況下,要求服務時間越短響應比越大,有利於短作業進程
要求服務時間相同,作業響應比由其等待時間決定,等待時間越長響應比越高,實現先來先服務
對於長作業,作業的響應比可以隨等待時間的增加而提高,等待時間足夠長時,其響應比可以升到很高,從而獲得處理機
不會導致飢餓
非搶占式的演算法

6.時間片輪轉演算法
使用與分時系統,使用時間片,就緒進程按照到達先後排成隊列,依次在時間片內佔用處理機,時間片達到時就釋放處理機
時間片選擇很重要,過大就變成了先來先服務,過短又變成了短作業優先
時間片影響因素:系統響應時間,就緒隊列中的進程進程數目和系統的處理能力
不會導致飢餓
搶占式

7.多級反饋隊列調度演算法
實現思想:設置多個就緒隊列,為每個隊列設置不同的優先順序,優先鉛茄級一次遞減。每個隊列中的時間片各不相同,時間片依次遞減。每個隊列按照先來先服務原則進行進程排隊,若規定時間片內沒有完成,就將進程放入下一級。只有到高級隊列為空的時候,低等級隊列才能開始調度

優點:
終端型作業用戶:源羨短作業優先
短批處理作業用戶:周轉時間較短
長批處理作業用戶:前面幾個隊列得到部分執行,不會長期得不到處理

產生「飢餓」現象

搶占式

熱點內容
安卓怎麼連接電腦用滑鼠 發布:2025-03-07 08:52:55 瀏覽:311
大數據與資料庫的關系 發布:2025-03-07 08:48:20 瀏覽:288
取冪C語言 發布:2025-03-07 08:43:10 瀏覽:488
高考解壓性 發布:2025-03-07 08:43:10 瀏覽:690
搜狐廣告伺服器是什麼 發布:2025-03-07 08:36:45 瀏覽:147
csgo穩定fps要什麼配置 發布:2025-03-07 08:35:01 瀏覽:404
matlab粒子群優化演算法 發布:2025-03-07 08:13:49 瀏覽:249
編譯原理翻譯 發布:2025-03-07 08:08:01 瀏覽:592
安卓光遇測試服為什麼伺服器錯誤 發布:2025-03-07 08:05:53 瀏覽:551
火狐緩存文件夾 發布:2025-03-07 08:05:51 瀏覽:113