天天看點

信号量與管程信号量(Semaphore)管程(Monitor)管程模型參考資料

信号量與管程都是作業系統的并發程式設計機制,也是現在很多進階語言實作并發的一種底層原理。

信号量(Semaphore)

信号量機制是由大名鼎鼎的荷蘭計算機科學家 Dijkstra 于1965 年提出的

作業系統的并發程式設計模型中,信号量(Semaphore)與鎖機制(Mutex)一樣都是對底層硬體同步方法的進階抽象

信号量與管程信号量(Semaphore)管程(Monitor)管程模型參考資料

信号量的模型

信号量模型的組成是這樣的:

  • 兩個成員變量:
    1. 整型數 count:用于記錄共享資源數量
    2. 等待隊列
  • 兩個基本方法:
    1. P() 操作:将 count - 1,若 count < 0 時,線程進入等待隊列(Prolaag 荷蘭語,嘗試減少)
    2. V() 操作:将 count + 1,若 count <= 0 時,喚醒一個等待隊列中的線程(Verhoog 荷蘭語,增加)

對信号量模型需要注意以下幾點:

  • 初始化信号量時,我們指定 count 的值,之後 count 值的變化隻能由 P() / V() 進行操作
  • 由作業系統實作并保證 P() / V() 操作的原子性
  • P() 操作是可能阻塞的,V() 操作不會阻塞
  • P() / V() 操作必須成對出現

信号量機制相比于鎖機制的一個主要差別是:信号量機制允許多個線程同時通路一個臨界區

因為隻要 count 符合條件,那麼線程就可以通路臨界區資源

信号量機制也存在一些缺點,那就是真正使用起來比較困難,因為當我們需要解決的同步問題越複雜,條件越多,那麼需要的信号量就越多,需要更加謹慎地處理信号量之間的處理順序否則很容易造成死鎖現象。

管程(Monitor)

管程是一種在信号量機制上進行改進的并發程式設計模型。

信号量與管程信号量(Semaphore)管程(Monitor)管程模型參考資料
  • 它采用了面向對象的思想封裝了線程間的同步控制
  • 在任意時刻最多允許一個線程執行管程代碼
  • 管程也允許線程主動釋放資源

管程模型

管程的組成如下:

  • 共享變量
  • 入口等待隊列
  • 一個鎖:控制整個管程代碼的互斥通路
  • 0個或多個條件變量:每個條件變量都包含一個自己的等待隊列,以及相應的出/入隊操作

注意:在入口等待隊列中的線程,都是條件滿足情況未知或曾經滿足過條件的線程,它們等待管程的新一輪執行,而條件變量的等待隊列中的線程必須等到滿足該條件後才可以重新回到入口等待隊列中去

管程模型相較于信号量模型的好處就是:易用,它可以把多個同步條件的操作都集中在一個子產品裡,進而簡化同步機制的實作難度

管程的模型可以分為三類:

  • Hansen模型:要求喚醒線程操作放在代碼最後,這樣可以保證目前線程在喚醒其他線程時已完成自己的所有操作
  • Hoare模型:線程可以在代碼任意位置執行喚醒操作,而且當喚醒其他線程後,自己立即阻塞,當被喚醒的線程完成操作後,再恢複自己
  • MESA模型:同Hoare一樣,可以再代碼任意位置執行喚醒操作,但被喚醒的線程不會立即執行,而是加入入口隊列等待執行,是以在實作中需要将條件檢查放入循環中,因為無法保證線程從喚醒到開始執行期間條件還是否保持滿足

參考資料

  1. 作業系統,向勇,清華大學,第十八講
  2. Java并發程式設計實戰,王寶令,極客時間