SylixOS下优先级反转与解决方案
admin
2023-03-15 06:21:01
0次

1. 概念

    一个高优先级线程通过信号量机制访问共享资源时,该信号量已被一个低优先级线程占有,而这个低优先级线程在访问共享资源时被其他的一些中等优先级线程抢占,因此造成高优先级线程被许多具有较低优先级的线程阻塞,称此现象为优先级反转。
    优先级反转会导致低优先级任务先于高优先级任务运行,在实时系统中会导致不可控的现象发生,因此,优先级反转在实时系统中是不可接受的。

2. 解决优先级反转

    高优先级任务不能执行的原因是因为低优先级占用了资源,而低优先级不能获得CPU,无法释放资源,所以解决优先级反转的原则是让低优先级任务尽快执行,释放资源。
SylixOS下解决优先级反转有优先级天花板策略(priority ceiling)和优先级继承策略(priority inheritance),且SylixOS下互斥信号量同时支持这两种策略。

2.1 优先级天花板

    优先级天花板策略是指将占有某资源的任务的优先级提高,提升到可能访问该资源的所有任务中最高优先级任务的优先级(这个优先级称为该资源的优先级天花板)。

2.2 优先级继承

    当发现高优先级的任务因为低优先级任务占用资源而阻塞时,就将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级。

3. 互斥量解决优级反转

3.1 互斥量属性块

    互斥量在创建时,需先创建互斥量属性块,SylixOS下互斥量属性块结构如程序清单 3.1所示。

程序清单 3.1 互斥量属性块结构

typedef struct {
    int          	PMUTEXATTR_iIsEnable;     	/*  此属性块是否有效           */
    int             	PMUTEXATTR_iType;       	/*  互斥量类型                 */
    int             	PMUTEXATTR_iPrioceiling;	/*  天花板优先级               */
    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下默认解决优先级反转方案是优先级继承策略。

3.2 提高优先级

    低优先级的任务占有资源,且高任务的优先级请求资源时,会尝试提高低优先级任务的优先级,在申请资源时调用_EventPrioTryBoost函数尝试提高任务优先级。

#include 
VOID  _EventPrioTryBoost (PLW_CLASS_EVENT  pevent, PLW_CLASS_TCB  ptcbCur)

    函数_EventPrioTryBoost原型分析:

  • 参数pevent为资源所属的事件控制块;

  • 参数ptcbCur为当前任务控制块。

    该函数根据互斥量属性块的属性设置,确定选用优先级继承策略或者天花板策略(SylixOS下默认是使用优先级继承策略),调用_SchedSetPrio函数改变任务的优先级。

3.3 恢复优先级

    低优先级任务释放互斥量时,调用EventPrioTryResume尝试恢复任务的优先级。

#include 
VOID  _EventPrioTryResume (PLW_CLASS_EVENT  pevent, PLW_CLASS_TCB   ptcbCur)

    函数_EventPrioTryResume原型分析:

  • 参数pevent为资源所属的事件控制块;

  • 参数ptcbCur为当前任务控制块。

    低优先级任务删除互斥量时,会尝试恢复任务优先级,代码片段如程序清单 3.3所示。

程序清单 3.3 尝试恢复优先级

if (ptcb) {
        ucPriority = (UINT8)pevent->EVENT_ulMaxCounter;	       /*  获得原线程优先级           */
	/*
	 *  拥有者优先级发生了变化,还原优先级
	 */
        if (!LW_PRIO_IS_EQU(ucPriority, ptcb->TCB_ucPriority)) {
        _SchedSetPrio(ptcb, ucPriority);
    }
}

4. 优先级设置函数

    在使用互斥量时,尝试提高或恢复任务优先级,调用SchedSetPrio函数进行优先级设置。

#include 
VOID  _SchedSetPrio (PLW_CLASS_TCB  ptcb, UINT8  ucPriority)

    函数_SchedSetPrio原型分析:

  • 参数ptcb为当前任务控制块;

  • 参数ucPriority为需设置的优先级。

    _SchedSetPrio函数改变任务的优先级,实现流程如图 4.1所示。

 SylixOS下优先级反转与解决方案

图 4.1 优先级设置流程


相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...