原文地址:https://blog.csdn.net/u014132720/article/details/80682137
vxworks是有一种强优先级调度的操作系统,即基于优先级抢占式调度。简单来说,就是当一个任务 highPri_task 的优先级比另一个任务lowPri_task的优先级高时,及时当前lowPri_task正在执行,highPri_task 也可以直接抢占CPU,优先运行这与linux基于时间片轮转的调度方式有本质的区别。
vxworks的强优先级调度会带来一个问题:
例如:存在优先级从高到低的3个任务:H,M,L这三个任务。
1. L任务首先请求一个与二进制信号量sem联系的资源S;
2. H由于优先级比L高,所以抢占CPU执行,但H也需要获取已经被L请求的资源S,此时H等待资源S被L释放,(如果H不是一直阻塞着去等待Z资源S,且等待时间小于L使用该资源的时间,则不会存在这个问题);
3. 如果在L使用资源S、H被阻塞的过程中,M抢占了CPU,而L没有释放其占用的资源S,那就可能导致H任务被迫延长不确定的阻塞时间。
为了避免这种高优先级的任务被相对较低优先级的任务变相阻塞,呈现出低优先级任务先执行的情况,vxworks引入了优先级转置(翻转)机制。
这种机制的原理是:
在使用信号量是,vxworks提供了一种可以附加的选项:SEM_INVERSION_SAFE,它允许使用优先级转置算法,同时,在创建信号量时semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE),其中SEM_INVERSION_SAFE的目的就是让信号量继承任务的高优先级。这种算法保证占有一个资源的任务,在其运行时,其优先级等于阻塞在改资源上的所有任务的优先级的最高值(实现优先级转置、翻转)。当执行完成后,这个任务释放资源,返回正常的优先级。
这样的优先级转置算法的效果是:低优先级的任务继承了阻塞在其占用资源的所有任务的最高优先级任务的优先级,这样,这个低优先级的任务就不会被优先级比它原有正常优先级高、但又比其继承的优先级低的任务抢占。
当然,这种优先级转置、优先级翻转必然会带来许多意想不到的奇葩问题。举个项目的例子:
存在如下3个任务:
TASK PRI
H1 10
H2 10
H3 20
L4 50
其中:
1. H1,L4共享资源S1;
2. H1,/H2任务优先级相同;
3. L3任务由于需要进行不断轮询动作,使用while(1)死循环,因此优先级设置比较低,为50;
首先,L4获取资源S1,并进行操作;
此时,H1优先级较高,意图抢占cpu,同时也需要获取共享资源S1;根据优先级转置规则,L4发生优先级翻转,优先级翻转为H1的优先级10并运行;
不幸的是,L4此时发生了异常,导致其在while(1)卡住,无法释放CPU;
导致的后果就是:所有优先级低于10(包括10)的任务全部无法得到CPU的调度;
---------------------
作者:MichaelJay2015
来源:CSDN
原文:https://blog.csdn.net/u014132720/article/details/80682137
版权声明:本文为博主原创文章,转载请附上博文链接!