1. 程式人生 > 實用技巧 >作業系統-李治軍-L16-程序同步與訊號量

作業系統-李治軍-L16-程序同步與訊號量

程序同步與訊號量

引例:
多程序合作要溝通好。
總不能售票員還在賣票的時候就開車。
在停車的時候,司機在等售票員的一個訊號,這樣他才可以開車。
在開車的時候,售票員也在等司機的一個訊號,這樣他才可以開門。
形成一種合理有序向前推進的工作。

程序同步的核心:等!等訊號!

但是,只發訊號還是解決不了全部問題。
如果框滿了,來了兩個生產者sleep在這裡,然後來了一個消費者,發出框沒滿的訊號量。
然後你怎麼喚醒別的程序呢?如果一起喚醒,那就會有衝突,如果只喚醒一個,那其他人就一直sleep在那裡。
所以不僅要記錄框裡面東西的數量,所以還需要記錄更全面的資訊,綜合成為最終的訊號量。
下面就設計一個量,來解決上面的問題。
再引入sem記錄,等的人數,sem=-1表示有一個人sleep
來了兩個sleep的人,就sem=-2了。
然後來了個消費者,消費完了一個東西,發現sem=-2,有兩個程序在等待,就在阻塞佇列裡喚醒一個人,然後sem=-1。
然後又消費了一個東西,再喚醒一個人,令sem=0了。
所以合理的方法是使用訊號來進行喚醒,而不是僅僅是counter,counter只能表示當前資源容量,但不能表示等待的程序數目。
如果消費者又消費了一個東西,就令sem=1。
這時候再來一個生產者,就sem=0,不需要等待。

所以,訊號量就是表明當前緩衝區容量(帶符號的)
實現:資料結構中包含量、以及當前資源個數。

S函式的寫法:發現還欠著貨,就喚醒別人。這裡沒有做佇列的切換。

S(semaphore s)
{
    s.value--;
    if(s.value<0){
    sleep(s.queue);}      
}
}

用訊號量解決生產者消費者問題
這裡引入了一個mutex進行原子操作,防止沒寫完、讀完就被別人打擾。