xenomai 应用开发 6:优先级反转 --WT

Xenomai应用开发:优先级反转与Mutex服务
本文介绍了Xenomai中优先级反转的现象及其解决方案,通过Mutex服务API创建、获取和释放互斥锁。优先级反转可能导致高优先级任务被低优先级任务阻塞,Xenomai的互斥锁通过优先级继承避免这个问题。文中通过火星探测器案例和实验室示例展示了优先级反转问题及如何使用Mutex消除它。

一、优先级反转

优先级反转发生在高优先级任务被迫无限期等待低优先级任务完成的情况下。例如,假设prioHigh、prioMedium和prioLow分别是高优先级、中等优先级和低优先级的任务。prioLow通过获取其关联的二进制信号量来获取资源。当prioHigh抢占prioLow并通过获取相同的信号量来争用资源时,它就会被阻塞。如果prioHigh被阻塞的时间不超过prioLow完成对资源的处理所花费的时间,那么就不会有问题,因为资源不能被抢占。但是,低优先级的任务很容易被中等优先级的任务prioMedium抢占,这会阻止prioLow放弃资源。这种情况可能会持续,在相当长的一段时间内阻塞prioHigh。
如下图所示:任务一开始运行并占有资源R1,当高优先级的任务3执行时,将打断任务1的执行,但是任务3也需要使用资源R1,与此同时任务2由挂起状态转为执行状态,任务2的优先级又比任务1的优先级高,此时任务2并不需要R1的资源,则CPU开始执行任务2,则高任务的任务3,将被迫等待任务2的执行完毕,并等待任务1释放资源R1.

在这里插入图片描述
在这里插入图片描述
为了解决优先级反转问题,Xenomai提供了一个所谓的互斥锁,它总是强制执行优先级继承协议来解决优先级反转问题。因此,当使用这个互斥锁时,将使用优先级继承算法此算法确保拥有受互斥锁保护的资源的任务始终以阻塞在该互斥锁上的最高优先级任务的优先级执行。当不再需要该资源时,该任务将放弃互斥锁并返回到正常的优先级。因此,可以防止具有中间优先级的任务抢占CPU。
著名的厕所理论
区分一下信号量与互斥量:

1、信号量哪里都可以释放,但互斥锁只有获得了其控制权的线程才可以释放,即:只有“锁上”它的那个线程才有“钥匙”打开它,有“所有权”的概念。

2、信号量可能导致线程优先级反转,而互斥锁可通过优先级继承的方法解决优先级反转问题

“火星探路者(Mars Pathfinder, MPF)”于1997年07月04日在火星表面着陆。在开始的几天内工作稳定,并传回大量数据,但是几天后,“探路者”开始出现系统复位、数据丢失的现象。
经过研发人员的分析,最后得出结论,就是因为系统里发生了优先级反转的问题。
火星探测器的优先级翻转
历史上几个因为编程开发中的错误或者漏洞造成惨痛损失的案例

二、 xenomai Mutex services API

1、创建一个互斥量,允许多个任务同步对共享资源的访问。

int rt_mutex_create  ( RT_MUTEX  * mutex,const char *  name 
	) 		

mutex :互斥体描述符的地址,在这个调用成功后,可以用来唯一地标识创建的对象。
name:代表互斥锁符号名的ASCII字符串
2、获取/锁定互斥锁

int rt_mutex_acquire 	( 	RT_MUTEX *  	mutex,RTIME  	timeout ) 	

mutex:互斥描述符
timeout:以时钟节拍表示的延迟
3、释放一个互斥锁

int rt_mutex_release 	( 	RT_MUTEX *  	mutex	) 	

此例程释放以前通过调用rt_mutex_acquire()或rt_mutex_acquire_until()锁定的互斥对象。如果互斥锁处于挂起状态,则第一个等待任务(按优先级顺序)将立即解除锁定并转移互斥锁的所有权;否则,互斥锁将保持未锁定状态。
更多mutexAPI

三、LAB About MUTEX

1、创建3个实时任务以不同的优先级,并且给于两个任务以同一个信号量资源,最终使任务发生优先级反转:
程序以及运行结果如图所示:
程序6a:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

#include <alchemy/task.h>
#include <alchemy/timer.h>
#include <alchemy/sem.h>
#include <alchemy/mutex.h>

#define NTASKS 3
RT_TASK task[NTASKS];
RT_SEM  low_high;


// function to be executed by task
void demo0(void *arg) {
   
   
   int i ;
    rt_task_sleep(1e9);//任务挂起1e9
     for(i=1; i < 4; i++)
    {
   
   
    rt_printf("Low priority task locks semaphore \n");
    rt_sem_p(&low_high,TM_INFINITE);
    int num = * (int *)arg;
    rt_timer_spin(2e9);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值