内核资料收集
1.
linux2.6的调度算法相较早期linux复杂很多. 通过设计, 该算法较好的解决了与可运行进程数量的比例关系, 它在固定的时间
内(与可运行的进程数量无关)选中要运行的进程. 也很好的处理了与处理器数量的比例关系, 因为每个CPU都拥有自己的可运行
进程队列. 而且, 新算法较好的解决了区分交互进程和批处理进程的问题.
调度程序总能成功地找到要执行的进程. 事实上, 总是至少有一个可运行进程, 即swapper, 它的PID等于0, 而且它只有在
CPU不能执行其他进程时才执行. 每个多处理器系统的CPU都有它自己的swapper进程, 其PID等于0.
每个Linux进程总是按照下面的调度类型被调度:
a. SCHED_FIFO
先进先出的实时进程. 当调度程序把CPU分配给进程的时候, 它把该进程描述符保留在运行队列链表的当前位置. 如果
没有其它可运行的更高优先级实时进程, 进程就继续使用CPU, 想用多久就用多久, 即使还有其他具有相同优先级的实时
进程处于可运行状态.
b. SCHED_RR
时间片轮转的实时进程. 当调度程序把CPU分配给进程的时候, 它把该进程的描述符放在运行队列链表的末尾. 这种策
略保证对所有具有相同优先级的SCHED_RR实时进程公平分配CPU时间.
c. SCHED_NORMAL
普通分时进程
调度进程根据进程是普通进程还是实时进程而有很大不同.
2. 普通进程的调度
a. 每个普通进程都有它自己的静态优先级, 调度程序使用静态优先级来估价系统中的这个进程与其它进程之间调度的程度. 内核
用从100(最高优先级)到139(最低优先级)的数表示普通进程的静态优先级. 值越大, 静态优先级越低.
b. 新进程总是继承其父进程的静态优先级. 用户可能通过nice()/setpriority()系统调用来改变自己拥有进程的静态优先级.
3. 基本时间片
静态优先级本质上决定了进程的基本时间片. 即进程用完了以前的时间片时, 系统分配给进程的时间片长度. 静态优先级和基本
时间片的关系用如下公式确定:
基本时间片(单位为ms) = (140 - prio) x 20 (100 < prio < 120)
基本时间片(单位为ms) = (140 - prio) x 5 (120 <= prio < 140)
静态优先级越高(prio值越小), 基本时间片越长. 其结果是, 与优先级低的进程比, 通常优先级较高的进程获得更长的CPU时间片.
......典型值......
4. 动态优先级和平均睡眠时间
a. 动态优先级是调度程序在选择新进程运行时候使用的数. 与静态优先级关系用下面的经验公式表示:
动态优先级=max(100, min(静态优先级 - bonus + 5, 139))
b. bonus是范围从0 - 10的值, 值小于5表示降低动态优先级以示惩罚, 值大于5表示增加动态优先级以示奖赏.
c. bonus的值与进程的"平均睡眠时间"相关. 平均睡眠时间是进程在睡眠状态所消耗的平均纳秒数. 注意, 这不是对过去时间的
求平均值. 至少TASK_INTERRUPTIBLE状态与TASK_UNINTERRUPTIBLE状态所计算出的平均睡眠时间是不同的. 而且进程在
运行过程中平均睡眠时间递减. 平均睡眠时间永远不能大于1s.
d. 平均睡眠时间和bonus的关系......略
e. 平均睡眠时间也被调度程序用来确定一个给定进程是交互进程还是批处理进程.
具体判断公式......略
5. 活动和过期进程
即使具有较高静态优先级的普通进程, 获得了较大的CPU时间片, 也不应该使用静态优先级较低的进程无法运行. 当一个进程
用完它的时间片时, 它应该被没有用完时间片的低优先级进程取代. 调试程序通过维持两个不相交的可运行进程集合, 来实现这
种机制:
a. 活动进程: 没有用完它们的时间片, 允许它们运行.
b. 过程进程: 已经用完时间片, 并因此禁止运行, 直到所有活动进程都过期.
总体方案中, 对批处理进程, 交互进程有不同的处理:
a. 活动的批处理进程用完其时间片后, 总是变成过期进程
b. 活动的交互式进程用完其时间片后, 通常仍然是活动进程(重填时间片并留在活动进程集合中)
c. 最老的过期进程等了很久, 或者过期进程比交互式进程的静态优先级高, 调度程序就把用完成时间片的交互式进程移到过期
进程集合中. 这样的结果是, 活动进程集合最终会变为空, 过期进程将有机会运行.
6. 实时进程的调度
实时进程都与一个实时优先级有关, 实时优先级是一个范围从1(最高优先级)到99(最低优先级)的值. 实时进程运行的过程中, 禁
止低优先级的进程运行. 实时进程总是被当成活动进程. 用户可通过系统调用sched_setparam()/sched_setscheduler()改变进程的
实时优先级.
几个可运行的实时进程具有相同的优先级, 调度程序选择第一个出现在本地CPU的运行队列相应链表中的进程.
实时进程会被另一个进程取代的条件:
a. 进程被另一个具有更高优先级的实时进程抢占
b. 进程执行阻塞操作并进入睡眠(TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE状态)
c. 进程停止(TASK_STOPPED或TASK_TRACED)或被杀死(EXIT_ZOMBIE或EXIT_DEAD状态)
d. 进程通过sched_yield()系统调用自愿放弃CPU
e. 进程是基于时间片轮转的实时进程, 且用完了它的时间片.
当系统调用nice()/setpriority()用于基于时间片轮转的实时进程时, 不改变实时进程的优先级而会改变其基本时间片长度.
基于时间片轮转的实时进程, 其基本时间片长度与实时进程的优先级无关, 而依赖于进程的静态优先级.
阅读(533) | 评论(0) | 转发(0) |