訊號量實現同步
舉個例子
- 在這裡司機啟動車輛需要售票員關車門,售票員開車門需要司機到站停車。
- 對於這兩個執行緒來說
- 需要設定兩個semaphore d=0;semaphore c=0;
- 為什麼呢,因為有執行順序的問題,只有售票員關門時候才可以啟動車輛,設定一個d=0,司機啟動汽車時候,這個執行緒執行p(d)來檢測,當為d=0,會進入等待的狀態。當售票員關門之後,這個執行緒執行V(d)操作,d++。這時司機執行p(d),就可以跳過等待狀態,去啟動車輛了。
- 同時售票員開車門需要司機到站停車也是這個道理,還需要另一個semaphore c=0;
- 為什麼初始化為0:
阻塞機制: 訊號量初始化為0是為了確保在相應的操作(如關閉門或到站停車)完成之前,相關的執行緒(如司機或售票員)會處於等待狀態。這種初始化方式確保了操作的先後順序,防止了例如司機在門未關閉時啟動車輛的情況,從而確保了系統的安全性和正確性。 - 同步問題
- 同步問題實質是將非同步的併發程序按照某種順序執行;
- 解決同步的本質就是要找到併發程序的互動點,利用P操作的等待特點來調節程序的執行速度。
- 通常初始值為0的訊號量可以讓程序直接進行等待狀態,直到另一個程序喚醒他。
經典同步問題
生產消費者問題
- 生產者(p)與消費者(c)共用一個緩衝區,生產者不能往“滿”的緩衝區中放產品,消費者不能從“空”的緩衝區中取產品。
Semaphore empty =1;//signal for producer
Semaphore empty=0;//signal for producer
Producer {
while(true){
make a product;
P(empty);
put the product into buffer;
V(full);
}
}
Consumer{
while(true){
P(full);
pick product from buffer;
V(empty);
consume the product;
}
}
- 這種方式是按照一定順序執行的。
- the bounded-buffer problem(有界緩衝區)
- 有界緩衝區問題,兩個執行緒“生產者”和“消費者”,同時使用一個固定長度的大小的緩衝區,生產者的主要是放入一定數量的資料到緩衝區中,然後重複此過程。與此同時,消費者也在緩衝區消耗這些資料。
- producer_i或consumer_i中的i表明有多個生產者和消費者,在許多個生產和消費者執行緒中,還需要解決當多個生產執行緒同時進入臨界區,多個消費執行緒進入臨界區。這些情況還是需要使用互斥鎖。
- 重要注意事件
- 不要隨意擴大臨界區
- empty和full的p,v操作不在同一個程序(同步訊號量)
- mutex的p,v操作在同一個程序(互斥訊號量)
蘋果橘子問題
- 問題描述
- 解決方案
- 需要去分析多個生產者和消費者之間的關係。首先是協作關係,生產蘋果的與消費蘋果的是協作關係,生產橘子與消費橘子是協作關係。生產蘋果與橘子之間又是競爭關係。
- 在程式碼中利用這種關係,V(sp)是消費者結束後,讓生產者去競爭。這個方式剛好解決了問題。