08進程同步與信號量

進程同步:指多個進程間互相合作,共同推進

比如大巴車司機和售票員兩個進程:司機必須等到售票員關門後,才能啓動車輛。售票員必須等司機到站停車才能開門。可以通過信號來完成,售票員在關門時發送信號1,司機等待信號1發生後,啓動車輛。司機到站停車發送信號2,售票員等待信號2發生後纔開門。

從紙上到實際:生產者-消費者實例

生產者和消費者共享一塊大小爲10的緩存。生產者每次執行時往緩存裏存1個單位內容,消費者每次從從裏面取一個單位。通過counter來控制兩個進程同步,當計數器等於緩存大小時,表明緩存已滿,並能再往裏放了,因此生產者進程需要阻塞起來(等待),當計數器爲0時說明緩存爲空,此時消費者進程需要阻塞。
因此需要讓進程走走停停來保證多進程合作的合理有序,通過喚醒信號來讓進程從阻塞態到就緒態,如下圖所示

但是當存在多個生產者和消費者時,只有信號並不能解決問題:

  1. 緩衝區滿以後生產者P1生產一個item放入,會sleep
  2. 又一個生產者P2生產一個item,會sleep
  3. 消費者C執行一次循環,counter==BUFFER_SIZE-1,發信號給P1,P1被wakeup
  4. 消費者C再執行1次循環,counter==BUFFER_SIZE-2,p2不能被喚醒。

 

此時conuter只能記錄剩餘的空間,並不能記錄有多少進程在睡眠(阻塞)

因此需要有個量記錄有多少進程在等待,從信號——>信號量

sem爲負值表示有多少個P在等待,sem爲正數表示還有多少個緩存空間
sem初值爲緩存空間大小。源碼如下:

semaphore表示信號量結構體,sleep動作就是將進程加入等待隊列。
 

V(semphore)
{
      s.value++;
      if(s.value<=0)
          wake(s.queue);
}
       


value爲負,則表示上一次有進程在等待,所以消費者取走一個後,需要從等待隊列裏喚醒一個P進程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章