Qnx任务调度

我们知道线程是操作系统进行任务调度的基本单位,那是谁来决定执行哪一个线程呢?
答案是操作系统内核,内核决定一个特定时刻哪个线程占有CPU。CPU有一组寄存器,当一个线程运行时,线程相关的信息会被存储到这些寄存器中(比如程序执行的位置,一些中间变量等)。当内核决定执行另一个线程时,它需要做以下事情:
1.保存当前运行线程的寄存器数据及其他上下文信息
2.加载将要执行进程的寄存器数据和上下文到CPU中
但是内核是如何判断该执行另一个线程了呢?它会查看在当前时间点是否有某个线程处于就绪状态。还记得对互斥锁的访问是如何管理的吗?没错,是根据线程的优先级和它等待的时长。内核使用相似的机制来决定下一个要执行的线程。有两个因素:优先级和调度略。
I.优先级
考虑两个准备好使用CPU的线程,如果它们拥有不同的优先级,答案很简单,内核会把CPU的使用权交给高优先级的线程。QNX线程的优先级从1开始往上加,数字越大优先级越高。需要注意的是0优先级是预留给Idle线程的,你不能使用。如果想知道你所使用的系统中线程优先级的最小值和最大值,可以使用函数schd_get_priority_min()和schd_get_priority_max()获取,它们在sched.h中声明。如果一个拥有更高优先级的线程突然变为可以占用CPU的状态,内核将会立刻加载该线程的上下文并开始执行。这个过程称为抢占,高优先级的线程抢占了低优先级线程对CPU的占用。当高优先级的线程执行完毕,内核会继续执行未执行完的低优先级线程。
现在,假设两个线程都准备好了占用CPU而且两个线程拥有相同的优先级。
II.调度策略
我们假设一个线程正在执行。让我们来看一下在这种情况下内核用来决定何时切换执行线程的规则。两个主要的策略是Round Robin(RR)和FIFO(First in, First out)。
i.FIFO
在FIFO策略中,一个线程可以一直占用CPU,直到它执行完。这意味着如果一个线程正在做一个非常长的数学计算而且没有其他更高优先级的线程就绪,这个线程就会一直执行下去。拥有相同优先级的线程会怎么样呢?它们会一直等待,当然更低优先级的线程也得不到执行。如果运行中的线程退出或者自愿放弃CPU的使用权,此时内核会寻找其他拥有相同优先级的就绪线程。如果没有这样的线程,内核会继续寻找更低优先级的就绪线程。自愿放弃CPU有以下两种情况。如果线程进入sleep,或被信号量阻塞,此时更低优先级的线程可以运行。另外一个是一个系统调用sched_yield(),仅仅让渡CPU给相同优先级的线程。如果一个线程调用了sched_yield(),而且没有相同优先级的线程就绪,此时会继续执行调用sched_yield()的线程。
ii.Round Robin
Round Robin的调度策略和FIFO类似,但是如果有相同优先级的线程就绪的话,当前线程不会永远执行下去。当前线程只执行一个系统定义好的时间片的时长,时间片的长度可以使用函数sched_rr_get_interval()获取。时间片的长度通常是4ms,不过实际上是ticksize的4倍,ticksize的值可以通过ClockPeriod()查询。内核启动一个RR线程的时候会开始计时,RR线程运行一段时间后分配给它的时间片将会用完。此时内核会检查是否有相同优先级的线程处于就绪状态,如果有,内核会让该线程开始执行,否则内核会继续让之前的线程执行并会再分配一个时间片给该线程。
对Qnx,Hypevisor或者智能座舱感兴趣的朋友欢迎关注微信公众号“汽车软件后花园”,我们一起学习交流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值