Linux内核设计与实现 第四章

Linux内核设计与实现  第四章

多任务

多任务系统可以划分为抢占式多任务和非抢占式多任务。进程在被抢占之前能够运行的时间叫时间片。Linux采用的就是抢占式多任务

Linux的进程调度

IO消耗型进程:频繁处于可运行状态但是只运行很短的时间。处理器消耗型:时间大多用在执行代码上,系统尽量降低其调度频率而延长运行时间。进程调度要在两个调度之间寻求平衡:响应时间短和最大系统利用率。

优先级:根据进程价值和处理器占用时间的分级方法。Linux采用了两种不同的优先级范围。第一种是nice值(-20到+19),默认是0:越大nice值则优先级越低,获得的处理器时间越少,在Linux中,nice值表示的是时间片的比例。第二种是实时优先级,范围是0~99,实时优先级越高表示进程优先级越高。

调度算法

unix进程调度中nice值的问题:(1)nice=0的往往是io进程,不需要太多时间片,nice=19的反而是CPU进程,需要更多时间片(2)nice为0和1时分到的时间片相差无几,但是nice为18和19时分到的时间片相差一倍(3)需要分配一个绝对时间片,这将引发一系列问题(4)某些时间片用完的进程该不该再次上CPU,难以保证公平

CFS(公平调度):进程获得CPU的时间由相对的nice值决定;nice值对应的使用时间不是绝对值,而是处理器使用比。

Linux调度的实现

时间记账:操作系统需要对每个进程的时间进账进行维护,CFS使用sched_entity调度器实体进行维护,它作为一个成员变量se嵌入在进程描述符task_struct内。比较重要的一个概念就是vruntime虚拟实时,它描述的不是运行时间,而是运行时间的标准化。例如操作系统中有两个进程,每个进程所需运行时间分别是20ms和80ms,刚开始,vruntime都是0,在运行10ms后,前者的vruntime是50ms,而后者的vruntime则为25ms。如我们所见,vruntime是每个进程的实际运行时间对总进程数的标准化。

进程选择:根据上面所述,显然我们每次都应该选择vruntime最小的进程,问题就在于我们如何找到这个进程——答案就是红黑树。具体细节不做过多描述。

调度器入口:schedule()。找到优先级最高的调度类,此调度类有一个自己的可运行队列,从中选出最高优先级的进程。

休眠:休眠有两种状态:能被信号唤醒的和不能被信号唤醒的,这两种状态都是通过同一个等待队列上,等待队列存在的形式是链表。进程通过执行下列步骤将自己放入队列:(1)创建等待队列项。(2)加入队列。(3)改变自己的状态。(4)信号唤醒进程,进程进入“迷糊”状态。(5)“迷糊”状态的进程再次检查条件,若真,则退出等待队列,否则继续睡。

唤醒:调用wake_up(),设置进程状态,调用enqueue_task()将进程放入红黑树。需要注意的是存在虚假的唤醒,需要用一个循环保证其等待条件真正达成。

进程上下文切换

context_switch()

schedule():虚拟内存的切换switch_mm(),处理器切换switch_to()。need_resched()来检查是否要重新进行调度。当进程应该被抢占时,此标志会被设置。抢占分为用户抢占和内核抢占。

实时调度

被实时调度器管理,而不是CFS调度器

SCHED_FIFO:不使用时间片,先入的任务执行到完毕才开始下一个,优先级比所有的SCHED_NORMAL高,只有更高优先级的SCHED_FIFO和SCHED_RR能抢占。

SCHED_RR:与SCHED_FIFO基本一致,唯一不同的是相同优先级的会基于时间片轮流运行。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章