读此篇文章之前必须事先已经理解了优先级反转,以及如何解决优先级反转的理念,不然下面理论无法理解。 先看一个例子,假设有task 1, task 2,task 3,优先级分别为5, 20, 25, 数字越小代表任务优先级越高。假设采用ucos 3的优先级继承的方式解决优先级反转。 下面的例子中涉及到的锁有mutex_1以及mutex_2。 void task1() { mutex_1_get(); (1) /*do something*/ (2) mutex_1_free(); (3) } void task2() { mutex_1_get(); (4) mutex_2_get(); (5) /*do something*/ (6) mutex_2_free(); (7) mutex_1_free(); (8) } void task3() { mutex_2_get(); (9) /*do something*/ (10) mutex_2_free(); (11) }
假设task 1以及task 2处于等待事件状态,处于阻塞状态。task 3 会首先运行,当task 3运行到(10)处的时候,任务task2被中断唤醒,然后接着运行task2,task 2 在(4)处获得mutex_1, 当task 2运行到(5)处时因为得不到mutex_2会被阻塞,按照ucos 3理念,为了解决优先级反转,task 3的优先级被task2 从25拉升到20。task 2阻塞的时候,接着task1 被中断唤醒然后task 1 开始运行,当task1 运行到(1)处的时候因为得不到mutex_1所以会被阻塞,按照ucos 3理念,为了解决优先级反转,task2的优先级被task1 从20拉升到5。然后继续返回task3运行(10)处。
这个时候我们来分析一下各个任务的优先级情况,task 1 为5,task2为5, task 3为20。这一切貌似都天衣无缝,有的读者已经想到有点什么不对头了。task 3在(10)处继续运行的时候会被其他任意优先级为5-19的任务可以随便抢占,如果有一个task 4优先级为15,可以随时打断task 3 的运行,到时再返回task 3运行到(11)处的时候,task 1和task 2 的等的黄花菜都凉了,本质上这个还是一个优先级反转的问题。
目前的rtos大部分都存在此类问题,包括当家花旦ucos 3。那应该怎么解决问题呢?解决方式只有在task 1处因为得不到mutex_1会被阻塞的时候,task 1除了要拉升task 2的优先级为5还要拉升task 3 的优先级到5 !此处是关键!只有task 3 被拉升到优先级5了才能保证不被任意优先级为5-19的任务抢占,能够最快的让task 2以及task 1运行。 上面的例子使用raw-os能够复现此问题,而且能很好地解决这个问题。Ucos 3 的mutex锁还有更多的问题,此处省略1000字。
[ 本帖最后由 jorya_txj 于 2013-12-19 12:01 编辑 ]
|