您好,登錄后才能下訂單哦!
一個高優(yōu)先級線程通過信號量機制訪問共享資源時,該信號量已被一個低優(yōu)先級線程占有,而這個低優(yōu)先級線程在訪問共享資源時被其他的一些中等優(yōu)先級線程搶占,因此造成高優(yōu)先級線程被許多具有較低優(yōu)先級的線程阻塞,稱此現(xiàn)象為優(yōu)先級反轉。
優(yōu)先級反轉會導致低優(yōu)先級任務先于高優(yōu)先級任務運行,在實時系統(tǒng)中會導致不可控的現(xiàn)象發(fā)生,因此,優(yōu)先級反轉在實時系統(tǒng)中是不可接受的。
高優(yōu)先級任務不能執(zhí)行的原因是因為低優(yōu)先級占用了資源,而低優(yōu)先級不能獲得CPU,無法釋放資源,所以解決優(yōu)先級反轉的原則是讓低優(yōu)先級任務盡快執(zhí)行,釋放資源。
SylixOS下解決優(yōu)先級反轉有優(yōu)先級天花板策略(priority ceiling)和優(yōu)先級繼承策略(priority inheritance),且SylixOS下互斥信號量同時支持這兩種策略。
優(yōu)先級天花板策略是指將占有某資源的任務的優(yōu)先級提高,提升到可能訪問該資源的所有任務中最高優(yōu)先級任務的優(yōu)先級(這個優(yōu)先級稱為該資源的優(yōu)先級天花板)。
當發(fā)現(xiàn)高優(yōu)先級的任務因為低優(yōu)先級任務占用資源而阻塞時,就將低優(yōu)先級任務的優(yōu)先級提升到等待它所占有的資源的最高優(yōu)先級任務的優(yōu)先級。
互斥量在創(chuàng)建時,需先創(chuàng)建互斥量屬性塊,SylixOS下互斥量屬性塊結構如程序清單 3.1所示。
程序清單 3.1 互斥量屬性塊結構
typedef struct { int PMUTEXATTR_iIsEnable; /* 此屬性塊是否有效 */ int PMUTEXATTR_iType; /* 互斥量類型 */ int PMUTEXATTR_iPrioceiling; /* 天花板優(yōu)先級 */ unsigned long PMUTEXATTR_ulOption; /* 算法類型 */ } pthread_mutexattr_t;
初始化互斥量時,如果不為互斥量屬性塊進行初始化,則使用默認屬性,SylixOS互斥量默認屬性塊如程序清單 3.2所示。
程序清單 3.2 默認互斥量屬性塊
static const pthread_mutexattr_t _G_pmutexattrDefault = { 1, PTHREAD_MUTEX_DEFAULT, /* 允許遞歸調用 */ PTHREAD_MUTEX_CEILING, (LW_OPTION_INHERIT_PRIORITY | LW_OPTION_WAIT_PRIORITY) /*PTHREAD_PRIO_NONE */ };
由默認互斥量默認屬性塊可知,SylixOS下默認解決優(yōu)先級反轉方案是優(yōu)先級繼承策略。
低優(yōu)先級的任務占有資源,且高任務的優(yōu)先級請求資源時,會嘗試提高低優(yōu)先級任務的優(yōu)先級,在申請資源時調用_EventPrioTryBoost函數嘗試提高任務優(yōu)先級。
#include <SylixOS.h> VOID _EventPrioTryBoost (PLW_CLASS_EVENT pevent, PLW_CLASS_TCB ptcbCur)
函數_EventPrioTryBoost原型分析:
參數pevent為資源所屬的事件控制塊;
參數ptcbCur為當前任務控制塊。
該函數根據互斥量屬性塊的屬性設置,確定選用優(yōu)先級繼承策略或者天花板策略(SylixOS下默認是使用優(yōu)先級繼承策略),調用_SchedSetPrio函數改變任務的優(yōu)先級。
低優(yōu)先級任務釋放互斥量時,調用EventPrioTryResume嘗試恢復任務的優(yōu)先級。
#include <SylixOS.h> VOID _EventPrioTryResume (PLW_CLASS_EVENT pevent, PLW_CLASS_TCB ptcbCur)
函數_EventPrioTryResume原型分析:
參數pevent為資源所屬的事件控制塊;
參數ptcbCur為當前任務控制塊。
低優(yōu)先級任務刪除互斥量時,會嘗試恢復任務優(yōu)先級,代碼片段如程序清單 3.3所示。
程序清單 3.3 嘗試恢復優(yōu)先級
if (ptcb) { ucPriority = (UINT8)pevent->EVENT_ulMaxCounter; /* 獲得原線程優(yōu)先級 */ /* * 擁有者優(yōu)先級發(fā)生了變化,還原優(yōu)先級 */ if (!LW_PRIO_IS_EQU(ucPriority, ptcb->TCB_ucPriority)) { _SchedSetPrio(ptcb, ucPriority); } }
在使用互斥量時,嘗試提高或恢復任務優(yōu)先級,調用SchedSetPrio函數進行優(yōu)先級設置。
#include <SylixOS.h> VOID _SchedSetPrio (PLW_CLASS_TCB ptcb, UINT8 ucPriority)
函數_SchedSetPrio原型分析:
參數ptcb為當前任務控制塊;
參數ucPriority為需設置的優(yōu)先級。
_SchedSetPrio函數改變任務的優(yōu)先級,實現(xiàn)流程如圖 4.1所示。
圖 4.1 優(yōu)先級設置流程
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。