1. 程式人生 > >UcosII 共享資源的鎖機制的處理

UcosII 共享資源的鎖機制的處理

                使用Ucosii作業系統編寫應用程式時,會經常使用到全域性變數等共享資源。若在使用時,如對全域性變數的同時的讀寫操作,可能會造成程式的崩潰,故在使用全域性變數時,要對其進行鎖或互斥處理。另,如果函式可以進行修改,則可通過函式的可重入性,即傳形參使用區域性變數,而避免使用全域性變數。

共享資源處理簡介:

(1)關中斷/開中斷          關、開中斷是獨佔共享資源最簡單也是最快捷的方法。μC/OS-Ⅲ訪問系統內部的變數和資料結構時,絕大部分使用的就是這種方法,一次來確保操作的“原子性”。這種方法也是任務和中斷服務程式共享變數或資料結構的唯一方法。          使用這種方法時,只要關中斷時間比系統本身關中斷時間短(或相同),就不會增加中斷延遲。然而儘管如此,仍要儘量避免關中斷,因為這將影響到系統對實時事件的響應能力。

 (2)給排程器上鎖/解鎖          如果任務不需要和中斷服務程式共享變數或資料結構,那麼可以通過給排程器上鎖的方法來訪問共享資源。需要注意的是,一旦給排程器上鎖,即使有更高優先順序的任務就緒了,也要等當前任務執行完畢,解鎖後才能切換到其他任務。也就是說一旦某個任務給排程器上鎖,那這個任務就成為了優先順序最高的任務。 

(3)訊號量          訊號量是一種上鎖機制,程式碼必須獲得對應鑰匙(解鎖)才能繼續執行。訊號量一共有6個相關API函式: 

1、OSSemCreat()         ---建立一個訊號量 

2、OSSemDel()             ---刪除一個訊號量 

3、OSSemPend()          ---等待一個訊號量 

4、OSSemPendAbort() ---取消等待 

5、OSSemPost()            ---釋放或者發出一個訊號量 

6、OSSemSet()              ---強制設定一個訊號量的值        

針對不同的情況一共有兩種訊號量。 

1、二進位制訊號量        當一個資源只有兩種狀態時(空閒、被佔用),則使用此訊號量。二進位制訊號量非0即1,當任務間共享變數、單一IO裝置時可使用此訊號量。 

2、計數型訊號量        計數型訊號量用於某資源可同時被幾個任務使用的情況。例如某個緩衝池(Buffer)有10個緩衝塊,任務可以申請其中一個緩衝塊,此時可使用技術型訊號量,且訊號量初始值被設定為10。當訊號量為0時,表示緩衝區滿,需要等待。        

訊號量是一個os_sem型別資料,包含5個成員:

1、Type          ---儲存變數型別; 

2、*NamePtr---儲存使用者給該變數定義的名字,用於除錯; 

3、PendList   ---該訊號量的任務掛起表; 

4、Ctr            ---訊號量的計數器成員; 

5、TS             ---時間戳,記錄訊號量上一次被釋放的時間。          優先順序反轉是使用訊號量要特別注意的問題,假設有兩個不同優先順序的任務同時使用一個訊號量,介於兩個優先順序之間還有一個優先順序的任務要執行,若高優先順序任務需要等待低優先順序任務釋放訊號量,則此時在任務排程過程中,會將高優先順序任務掛起,首先執行中等優先順序任務,然後執行低優先順序任務,待低優先順序任務釋放訊號量後,再執行高優先順序任務。此時高優先順序任務已經降到和低優先順序任務相同的優先順序。在使用訊號量時要特別注意這種情況。     

(3)互斥型訊號量         互斥型訊號量是一種特殊的二進位制訊號量,其與普通訊號量唯一的不同在於一旦一個高優先順序的任務需要依賴低優先順序任務釋出訊號量,則將低優先順序任務的優先順序暫時提高到與高優先順序任務相同的優先順序,帶訊號量釋出完成後,再恢復其優先順序。  互斥型訊號量有5個API函式: 

1、OSMutexCreate()        ---建立一個互斥型訊號量 

2、OSMutexDel()             ---刪除一個互斥型訊號量 

3、OSMutexPend()          ---等待一個互斥型訊號量 

4、OSMutexPendAbort()---取消等待  

5、OSMutexPost()           ---釋放或釋出一個互斥型訊號量 

互斥型訊號量是一個os_mutex型別資料,包含7個成員: 

1、Type          ---儲存變數型別; 

2、*NamePtr---儲存使用者給該變數定義的名字,用於除錯; 

3、PendList   ---該訊號量的任務掛起表; 

4、*OwnerTCBPtr---如果互斥型訊號量被一個任務佔用,則該成員儲存該任務的OS_TCB。  5、OwnerOriginalPrio---記錄任務佔有互斥型訊號量之前的優先順序。 

6、Ctr            ---μC/OS-Ⅲ允許任務多次巢狀“獲取”互斥型訊號量,但是釋放次數必須和獲取次數一樣多。 

7、TS             ---時間戳,記錄訊號量上一次被釋放的時間。 

二、死鎖          死鎖(deadlock)也叫做抱死(deadly embrace),指兩個任務無限制地相互等待對方控制著的資源。          假設某一時刻,任務A獲取資源X,任務B獲取資源Y,執行一段時間後,任務A和任務B均未釋放資源,此時任務A試圖獲取資源Y,任務B試圖獲取資源X,則發生死鎖。 

避免死鎖的方法有三種: 

1、先得到全部需要的資源,再做下一步工作; 

2、用相同的順序申請多個資源; 

3、在呼叫請求訊號量的函式中設定超時時間,該方法僅可以暫時緩解,但是有可能導致死鎖重複出現多次。 

上述三個方法中,個人建議嚴格按照方法2來避免死鎖。