電電俠 ? (神秘兮兮地)科,你知道嗎?程序世界里有個神奇的小開關,叫做“二值信號量”。
(若有所思)二值信號量?我略有了解。
科科君
信號量本質上是一個程序數據項,用于決定任務繼續運行還是掛起。信號量類型有兩種,二值信號量和通用型/計數信號量。兩者的工作原理相同,信號量原語最初由?Edsger Dijkstra在1965年提出。
電電俠 ? 科科大大分析下? ? 首先分析二值信號量。
科科君
本質上,二值信號量是一個任務流控制機制,可以將其比作鐵路信號
火車將根據信號位置情況,決定通過該點還是必須停止。如果火車停下來,它們會保持在該位置直到信號變為“允許通行”。以類似的方式,信號量可以允許任務繼續執行其代碼或掛起。一旦任務掛起,它將保持在此狀態,直到某些程序操作使該任務重新就緒。
電電俠 ? 在鐵路系統中,信號可算是安全機制。 ? 是的,這種安全機制用于控制列車運行,從而防止碰撞、損壞或人身事故。
科科君
實際的鐵路網絡中還有很多信號,可根據需要使用這些信號。同樣,多任務設計中也可能使用許多信號量,每個信號量都相當于一個特定的信號。
在并發軟件中,信號量用于兩個截然不同的目的。此處描述的功能是作為互斥(消除爭用)機制,每個共享資源分配一個信號量。信號量也用于同步,實現任務交互。
電電俠 ? 有沒有類似的信號量的概念圖。 ? 下圖為用于訪問控制時信號量的概念。
科科君
二值信號量用于互斥—概念
該類比是停車場入口控制,信號量相當于控制機制。這里的共享資源是一個單獨的停車位,用于上下客。需要確保有且只有一輛車可以進入停車位。因此,用戶在嘗試停車之前,必須首先檢查停車位是否空閑。為此使用了一個訪問控制接口,其包括:
(1)“請求”按鈕。用戶按下此按鈕以向停車場服務員發出需要進入停車場的信號。
(2)“結束”按鈕。用戶在退出時,按此按鈕通知服務員,停車位再次空閑。
(3)揚聲器。停車場服務員用它來回答用戶的請求。
在此類比中,二進制信號量等價于訪問控制機制的軟件實現,這里用戶指的是任務。
電電俠 ? 我知道。假設最初停車場資源處于空閑狀態。第一個操作是向停車場服務員提供此狀態信息 (假設從控制室看不到停車位)。其對應的軟件操作將初始化該信號量。同樣,服務員功能由操作系統軟件提供。 ? 是的。當然,還有以下情況。
科科君
當用戶需要使用停車資源時,它靠近屏障并按下請求按鈕,在信號量術語中,該行為被定義為信號等待(wait)操作。由于資源處于空閑狀態,故服務員抬起屏障并回答可以通過,?用戶隨即進入保護區域,然后屏障關閉。
某個時刻用戶離開并騰出停車位,在退出時按下結束按鈕,發出信號給訪問控制機制, 該行為被定義為信號發布(signal)操作。操作結果將更新服務員看到的狀態信息,顯示停車場再次空閑。
電電俠 ? 那當另一輛車到達時資源正在使用時,請求服務的用戶該怎么辦? ? 該用戶會被放置到等待隊列(對應于任務掛起)。
科科君
當前資源占用者,一旦完成工作,在離開停車位時將生成一個信 號,控制機制收到該信號,標記資源空閑。但隨后的事件遵循了不同的模式,沒有更新服務員的狀態信息。取而代之的是抬起屏障并發送“通過”消息給等待的用戶(相當于一個任務喚醒另一個任務),授權用戶進入保護區域;后續的事件處理過程與前面一致。
電電俠 ?
當任務1已經處于等待隊列中時,一個更高優先級的任務(比如任務3)到達,系統如何處理?
實際上,結果取決于使用的排隊策略。通常隊列使用兩種排隊策略,先進先出(FIFO)策略和優先級搶占策略。
科科君
使用先進先出策略排隊時,任務3排在任務1的后面。因此條件允許(即空間可用)時, 任務1可以立即執行。此方式雖然安全,但導致較低優先級的任務延遲了較高優先級任務 的執行,可能導致嚴重的系統問題。
如果使用優先級搶占策略,任務3優先并排在隊列前面,因此它將第一個就緒。但該方式延遲了任務1的執行,也會導致潛在的性能問題(任務饑餓)。由設計者來決定使用哪種方法以及在何處使用它,但無論哪種情況,任務行為建模都如下圖所示。
任務行為建模
如前所述,為每個受控的資源創建一個信號量,在編程術語中,信號量被看作一個命名的數據項。下面來看一個簡單的應用程序。
科科君 ? ? 簡單應用程序
首先創建一個信號量,命名為CoefficientsSemaphore,可執行的操作包括等待信號量 Wait(CoefficientsSemaphore)和發 布信號量Signal(CoefficientsSemaphore)。二進制信號量只有兩個值,“0”或“1”?!?”表示資源正在使用中,“1”表示資源當前空 閑。在其初始形式中,信號量操作見代碼清單1和代碼清單2。
代碼清單1
代碼清單2
在程序中,將在需要的位置使用上述代碼段,如代碼清單3所示。
代碼清單3
電電俠 ? 那定義wait和signal操作為什么類型? ? wait和signal操作被定義為“原語”類型,即每個操作都是不可分割的。
科科君
換言之,一旦 wait或signal處理開始,其對應的機器指令序列不能被中斷。這是必不可少的,否則會遇到和單一標志互斥機制相同的問題。提供原子性操作不是一件輕松的任務,它可能會帶來實現上的困難,但系統必須克服困難實現信號量。此外,這些原語操作必須由操作系統而非程序員保護。
二進制信號量可以實現為單字節,甚至是字節中的一位,使用一條“位設置和測試”指令 39 實現。但是,如果測試和檢查涉及多條處理器指令時,該方法行不通。在這種情況下,通過在信號量操作執行之前禁用系統中斷,確保操作的原子性。資源操作完成后,重新啟用中斷。
(敲黑板)
科科君
此技術通常不適用于多處理器系統,多處理器系統需要一種硬件鎖定機制。wait和signal也稱為 P操作和 V 操作,源自荷蘭語詞匯。關于它們實際指代的詞存在一些分歧,最流行的是prolaag和verhogen。
原語是為完成特定的功能而編寫的一段程序,它在執行時不可分割、不可中斷。
審核編輯:黃飛
評論