优先级反转和解决方法

来源:互联网 发布:c语言运算符结合方向 编辑:程序博客网 时间:2024/04/26 14:17

优先级反转的描述:

假设任务1,任务2,任务3;他们的优先级顺序分别为1 > 2 > 3。有一个稀缺资源S,S由一个信号量控制为互斥访问。

  1. 任务3正在执行,并申请到了资源S;
  2. 任务1抢占了任务3的执行,任务3挂起,任务1执行;
  3. 任务1申请资源S,发现被占用,所以挂起,任务3恢复执行;
  4. 任务2抢占了任务3的执行,任务3挂起,任务2执行;
  5. 任务2执行完毕,任务3恢复;
  6. 任务3释放资源S,任务1抢占资源S,任务1执行,任务3挂起;
  7. 任务1执行完毕,任务3执行。

以上可以看出,任务2虽然比任务1优先级低,但是比任务1优先执行。也就是说任务1的优先级被降低到了任务3的级别。


分析

由于稀缺资源S的独占性,任务3在申请到资源后,任务1必然会在任务3释放资源后才能执行完成。而任务2肯定会抢占任务3的执行。这个时候,要想任务1比任务2之前执行,有两种方法:任务3释放资源,任务2不能抢占任务3。

  • 任务3释放资源。这条路走不通,因为独占资源没有操作完成就释放,要么回滚,要么出错。(X)
  • 任务2不能抢占任务3。提升任务3的优先级高于任务2就可以了。(V)提高到多少?假如任务1和任务5共抢资源S,那么任务2、3、4都有可能抢去任务5的执行权,所以任务提升一定要和资源S被申请的最高优先级平等或者大于。对于有相同优先级的内核来说,任务5提升到任务1的优先级即可,对于优先级单一的内核,如ucos,就要提升到高一点。

解决方法

  1. 优先级天花板。当任务3使用资源S时,就把任务3的优先级提升到能访问资源S的最高优先级,执行完成释放资源之后,把优先级再改回来;这样的方法,简单易行,解决了多个高优先级任务抢占资源S的问题。但是带来了一些缺点,就是不一定每次都有高优先级任务抢占资源S,每次都提升优先级是对CPU资源的一种浪费。
  2. 优先级继承。当任务3使用资源S时,任务1抢占执行权,申请资源S,比较资源1和资源3的优先级,假如任务1优先级高,才提升任务3,提升到和任务1相同的优先级,当任务3释放资源后,将优先级再调整回来。相对于优先级天花板方法,相当于延后执行,克服了任务1的缺点,自己本身的特点是,逻辑复杂,需要操作系统支持相同优先级。在ucos中不容易实现。
  3. 两者结合的方案:当任务3使用资源S时,任务1抢占执行权,申请资源S,比较资源1和资源3的优先级,假如任务1优先级高,才提升任务3,提升到能访问资源S的最高优先级,当任务3释放资源后,将优先级再调整回来。