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