互斥量和訊號量的區別
1. 互斥量用於線程的互斥,訊號線用於線程的同步。
這是互斥量和訊號量的根本區別,也就是互斥和同步之間的區別。
互斥:是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。但互斥無法限制訪問者對資源的訪問順序,即訪問是無序的。
同步:是指在互斥的基礎上(大多數情況),通過其它機制實現訪問者對資源的有序訪問。在大多數情況下,同步已經實現了互斥,特別是所有寫入資源的情況必定是互斥的。少數情況是指可以允許多個訪問者同時訪問資源
2. 互斥量值只能為0/1,訊號量值可以為非負整數。
也就是說,一個互斥量只能用於一個資源的互斥訪問,它不能實現多個資源的多線程互斥問題。訊號量可以實現多個同類資源的多線程互斥和同步。當訊號量為單值訊號量是,也可以完成一個資源的互斥訪問。
3. 互斥量的加鎖和解鎖必須由同一線程分別對應使用,訊號量可以由一個線程釋放,另一個線程得到。
互斥訊號量功能:
1) 實現對資源的獨佔式訪問(二值訊號量)。
2) 降解優先順序反轉。
優先順序反轉:
使用即時核心,
優先順序反轉問題是即時系統中出現得最多的問題。設,任務1優先順序高於任務2,任務2優先順序高於任務3。任務1和任務2處於掛起狀態,等待某一事件的發生,任務3正在運行如。此時,任務3要使用其共用資源。使用共用資源之前,首先必須得到該資源的訊號量(Semaphore)。任務3得到了該訊號量,並開始使用該共用資源。由於任務1優先順序高,它等待的事件到來之後剝奪了任務3的CPU使用權,任務1開始運行。運行過程中任務1也要使用那個任務3正在使用著的資源,由於該資源的訊號量還被任務3佔用著,任務1隻能進入掛起狀態,等待任務3釋放該訊號量。任務3得以繼續運行。由於任務2的優先順序高於任務3,當任務2等待的事件發生後,任務2剝奪了任務3的CPU的使用權並開始運行。處理它該處理的事件,直到處理完之後將CPU控制權還給任3。任務3接著運行,直到釋放那個共用資源的訊號量。直到此時,由於即時核心知道有個高優先順序的任務在等待這個訊號量,核心做任務切換,使任務1得到該訊號量並接著運行。
在這種情況下,
任務1優先順序實際上降到了任務3 的優先順序水平。因為任務1要等,直等到任務3釋放佔有的那個共用資源。由於任務2剝奪任務3的CPU使用權,使任務1的狀況更加惡化,任務2使任務1增加了額外的延遲時間。任務1和任務2的優先順序發生了反轉。
糾正的方法可以是,
在任務3使用共用資源時,提升任務3的優先順序。任務完成時予以恢複。任務3的優先順序必須升至最高,高於允許使用該資源的任何任務。多任務核心應允許動態改變任務的優先順序以避免發生優先順序反轉現象。然而改變任務的優先順序是很花時間的。如果任務3並沒有先被任務1剝奪CPU使用權,又被任務2搶走了CPU使用權,花很多時間在共用資源使用前提升任務3的優先順序,然後又在資源使用後花時間恢複任務3的優先順序,則無形中浪費了很多CPU時間。真正需要的是,為防止發生優先順序反轉,核心能自動變換任務的優先順序,這叫做優先順序繼承(Priority
inheritance)。
互斥訊號量降解優先順序反轉的過程:
設mutex已被低優先順序的任務3佔用。高優先順序的任務1提出申請mutex(調用Pend())。在這種情況下:
1) Pend函數注意到高優先順序的任務要用這個共用資源,於是將任務3的優先順序升高至9(建立mutex時指定,比任何提出申請mutex的任務的優先順序都要高),並強制任務調度(由於任務3的優先順序升高至9,因此任務3執行),任務3繼續使用共用資源。當共用資源使用完後,任務3調用Post函數,釋放mutex。
2)Post函數注意到原來佔用這個mutex的任務的優先順序是被太高的,於是將任務3的優先順序恢複到原來水平。
3)Post還注意到有個高優先順序的的任務(任務1)正在等待這個mutex,於是將mutex交給這個任務,並做任務切換,讓任務1運行。
互斥訊號量的組成:
一個標誌,指示mutex是否可用(OS_MUTEX_AVAILABLE表示可用)。
一個優先順序,即優先順序繼承優先順序(PIP)。
一個等待mutex的工作清單。