一、Linux2.6调度算法的特点

1.在固定时间内选中要运行的进程,这个时间不会因为可运行进程增多而变大
2.每个CPU有自己的可运行队列
3.较好地解决区分交互式进程与批处理进程的问题

二、进程按调度类型分类

1.SCHED_FIFO:先进先出的实时进程
如果没有其它更高优先级(必须是更高)的可运行实时进程(普通进程的优先不可能高于实时进程)出现,就可以一地上运行。
对于这种进程,时间长度是没有意义的。
2.SCHED_RR:时间片轮转的实时进程
所有具有同优先级(且都是当前情况下优先级最高)的SCHED_RR以时间片轮转的方式公平地分配CPU
3.SCHED_NORMAL:时间片轮转的普通进程
时间片用完后会变成过期进程。所有的进程都成为过程进程后,再统一把过期进程变为活动进程
1和2永远不会成为过期进程

三、进程的类型与优先级的关系

|| 静态优先级| 动态优先级| 实时优先级|

FIFO 无 无 (1)(2) RR (2)(3) 无 (1) NORMAL (2)(3)(4) (1)(5) 无 note: (1)决定其在运行队列中的位置,即调度选择哪一个进程作为新进程是由它决定的 (2)可通过nice()或setpriority()来改变其值 (3)初始值从父进程继承而得,决定了时间片的基本长度,值越小,基本时间片就越长 (4)对动态优先级有值有影响 (5)其依赖于过去的平均睡眠时间,平均睡眠时间长(倾向于交互式进程)的优先级高,平均睡眠时间短(倾向于批处理进程)的优先级低

四、更新进程的时间片 1.FIFO:没有意义 2.RR:递减时间片,如果时间片用完,执行以下操作 (1)重填进程的时间片数 (2)设置进程的TIF_NEED_RESCHED标志,强制调用schedule()切换进程 (3)把进程描述符移动与当前进程优先级相应的运行队列活动链表的尾部 3.NORMAL:递减时间片,如果时间片用完,执行以下操作 (1)从活动队列中删除该进程 (2)设置进程的TIF_NEED_RESCHED标志,强制调用schedule()切换进程 (3)计算新的动态优先级 (4)重填时间片 (5)把该进程加入过期队列中

五、调度只发生于以下两种情况 1.直接调用:进程因不能获得资源而阻塞时,直接调用schedule() 2.间接调用:内核态恢复用户态前检查TIF_NEED_RESCHED标志,如果置位,就调用schedule() 执行以下操作,会将TIF_NEED_RESCHED标志置位 (1)进程用完时间片 (2)一个被唤醒的进程比新进程的优先级高 (3)发出进程调度的系统调用

六、调度函数schedule() 0.schedule() ----->调度函数 (1)禁止内核抢占,禁止本地中断 (2)如果prev不是可运行状态,则把它从运行队列中删除 (3)若本地可运行队列中有可运行进程,则调用dependent_sleeper()选择一个进程(见1) 若本地无可运行队列,则迁移一些可运行进程到本地load_balance() 若迁移失败,则选择swapper进程作为next (4)把next的task_struct的第一部分字段装入硬件高速缓存 (5)减少prev的平均睡眠时间 (6)若prev和next是同一进程,则不切换 (7)建立next的地址空间 (8)switch_to()(见Linux2.6进程切换)(见2) (9)打开本地中断,打开内核抢占

1.dependent_sleeper() -----> 选择一个进程 (1)检查可运行队列,若没有活动,则把所有过期进程这为活动进程 (2)从活动队列中搜索一个可运行进程作为next (3)增加进程的睡眠时间(见3)

2.关于switch_to() switch_to宏调用 之后紧接着的指令并不是由next进程立即执行,而是稍后当调度程序又选择prev执行时由prev执行的 然而,那时的prev不是指向schedule()中的被换出的进程,而是指向prev被调度时被prev换出的进程

3.关于“增加进程睡眠时间” 调度程序把被中断处理程序和可延迟函数所唤醒的进程与被系统调用服务程序和内核线程所唤醒的进程区分开。 对于前者,增加全部运行队列的等待时间 对于后者,只增加等待时间的部分 因为交互进程更可能被异步事件而不是同步事件唤醒

results matching ""

    No results matching ""