優(yōu)先級翻轉(zhuǎn)與優(yōu)先級繼承
優(yōu)先級翻轉(zhuǎn)在可剝奪內(nèi)核中是非常常見的,例子如下(H:High、M:Middle、L:Low)
任務(wù) H 和任務(wù) M 處于掛起狀態(tài),等待某一事件的發(fā)生,任務(wù) L 正在運行。
某一時刻任務(wù) L 想要訪問共享資源,在此之前它必須先獲得對應(yīng)該資源的信號量。
任務(wù) L 獲得信號量并開始使用該共享資源。
由于任務(wù) H 優(yōu)先級高,它等待的事件發(fā)生后便剝奪了任務(wù) L 的 CPU 使用權(quán)。
任務(wù) H 開始運行。
任務(wù) H 運行過程中也要使用任務(wù) L 正在使用著的資源,由于該資源的信號量還被任務(wù)L 占用著,任務(wù) H 只能進入掛起狀態(tài),等待任務(wù) L
釋放該信號量。
任務(wù) L 繼續(xù)運行。
由于任務(wù) M 的優(yōu)先級高于任務(wù) L,當任務(wù) M 等待的事件發(fā)生后,任務(wù) M 剝奪了任務(wù)L 的 CPU 使用權(quán)。
任務(wù) M 處理該處理的事。
任務(wù) M 執(zhí)行完畢后,將 CPU 使用權(quán)歸還給任務(wù) L。
任務(wù) L 繼續(xù)運行。
最終任務(wù) L 完成所有的工作并釋放了信號量,到此為止,由于實時內(nèi)核知道有個高優(yōu)先級的任務(wù)在等待這個信號量,故內(nèi)核做任務(wù)切換。
任務(wù) H 得到該信號量并接著運行。
在這種情況下,任務(wù) H 的優(yōu)先級實際上降到了任務(wù) L 的優(yōu)先級水平。因為任務(wù) H 要一直等待直到任務(wù) L 釋放其占用的那個共享資源。由于任務(wù) M剝奪了任務(wù) L 的 CPU 使用權(quán),使得任務(wù) H 的情況更加惡化,這樣就相當于任務(wù) M 的優(yōu)先級高于任務(wù) H,導致優(yōu)先級翻轉(zhuǎn)。
Linux 用 rt_mutex 來解決該問題,rt_mutex 是帶優(yōu)先級繼承的互斥鎖。
當一個 rt_mutex 正在被一個低優(yōu)先級的任務(wù)使用,而此時有個高優(yōu)先級的任務(wù)也嘗試獲取這個 rt_mutex的話就會被阻塞。不過這個高優(yōu)先級的任務(wù)會將低優(yōu)先級任務(wù)的優(yōu)先級提升到與自己相同的優(yōu)先級,這就是優(yōu)先級繼承。優(yōu)先級繼承盡可能的降低了高優(yōu)先級任務(wù)處于阻塞態(tài)的時間,并且將已經(jīng)出現(xiàn)的“優(yōu)先級翻轉(zhuǎn)”的影響降到最低。
優(yōu)先級繼承并不能完全的消除優(yōu)先級翻轉(zhuǎn),它只是盡可能的降低優(yōu)先級翻轉(zhuǎn)帶來的影響。
rt_mutex 不能用于中斷服務(wù)函數(shù)中,原因如下:
rt_mutex 有優(yōu)先級繼承的機制,所以只能用在任務(wù)中,不能用于中斷服務(wù)函數(shù)。
中斷服務(wù)函數(shù)中不能因為要等待 rt_mutex 而設(shè)置阻塞時間進入阻塞態(tài)。
在 i2c_transfer 調(diào)用 __i2c_transfer 之前,就加了 rt_mutex,保證 I2C 傳輸盡快執(zhí)行。
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1373瀏覽量
40310 -
子系統(tǒng)
+關(guān)注
關(guān)注
0文章
109瀏覽量
12412 -
I2C
+關(guān)注
關(guān)注
28文章
1489瀏覽量
123900
發(fā)布評論請先 登錄
相關(guān)推薦
評論