概述
多工系統中存在一種潛在的風險,當一個任務在使用某個資源的過程中,即還沒有完全結束對資源的訪問時,便被切出執行態,使得資源處於非一致,不完整的狀態,如果這個時候有另一個任務或者中斷來訪問這個資源,則會導致資料損壞或者其他相似的錯誤。
會發生該問題的情景:
- 對外設的操作
- 讀-改-寫操作
- 變數的非原子訪問
- 函式重入
一個函式只訪問自己棧空間上的資料或者是核心暫存器中的資料,不訪問其他任何資料,比如全域性變數啥的,則這個函式就是重入的。否則不可重入。
互斥
互斥保證資源在被訪問後具有排他性,防止資源被意外修改
最高的互斥方法
儘量不要共享資源,或者是每個資源都通過單任務訪問。
互斥的方法
臨界區與掛起排程器
- 基本臨界區
臨界區指在訪問資源前,關閉全部中斷,在訪問資源後,再恢復中斷,是一種非常原始的方法。
臨界區必須只具有很短的時間,否則會反過來影響中斷響應時間
- 掛起(鎖定)排程器
掛起排程器,保證程式碼區不會被其他任務或中斷打斷。
互斥量
互斥量是一種特殊的二值訊號量,用於控制在兩個或多個任務間訪問共享資料。
互斥量的機制:
一個任務想要合法地訪問資源,必須先成功的得到該資源對應的令牌,當完成對資源的使用後,必須馬上歸還令牌。只有歸還了令牌,其他任務才可能訪問共享資源。
互斥量和二值訊號量的區別:
- 用於互斥的訊號量必須歸還
- 用於同步的訊號量通常是完成同步後便丟棄,不再歸還
優先順序反轉
互斥量容易導致一個問題是優先順序反轉,優先順序反轉會導致重大問題
即高優先順序任務因為無法獲取互斥訊號,而阻塞,導致低優先順序優先執行。
更嚴重的一種情形:
低優先順序先執行,獲得互斥量,高優先順序無法獲得互斥量而阻塞,這時候,一箇中等優先順序任務開始執行,搶佔了低優先順序,然後低優先順序任務block了,無法give互斥量,從而高優先順序也無法執行。
優先順序繼承
最小化減少優先順序反轉的負面影響,但不能完全消除。
通過暫時的將互斥量持有者的優先順序提升至所有等待此互斥量的任務所具有的最高優先順序,互斥量持有者歸還互斥量後,優先順序會自動設定為其原來的優先順序。
死鎖
兩個資源都等待被對方持有時,兩個任務都無法再繼續執行,這種情況成為死鎖。
守護程式
守護程式提供一種乾淨利落的方法來實現互斥功能,而不用擔心會發生優先順序反轉和死鎖。
守護任務是對某個資源具有唯一所有權的任務,只有守護任務才可以直接訪問其守護的資源,其他任務要訪問該資源只能簡介的通過守護任務提供的服務。
守護程式的實現機制:
利用佇列,當其他任務想使用某個資源的時候,通過佇列傳送訊息給守護程式,由守護程式對資源進行操作。