内核资料收集
进程链表链接所有的进程描述符. 运行队列链表链接所有的可运行进程的进程描述符, swapper进程(idle进程)除外
1. 数据结构runqueue(改名struct rq了, 实现过程有变化)
系统中每个CPU都有它自己的运行队列, 所有的runqueue结构存放在runqueue每CPU变量中. this_rq()产生本地CPU运行队列
地址, 而宏cpu_rq(n)产生索引为n的CPU的运行队列的地址.
runqueue结构字段
......
prio_array_t * active 活动进程表指针
prio_array_t * expire 过期进程表指针
prio_array_t [2] arrays 活动进程和过期进程的两个集合
......
runqueue结构的active字段指向arrays中的其中之一, 对应于包含活动进程的可运行进程集合. expired字段指向数组中
的另一个, 对应于包含过期进程的可运行进程集合. arrays中两个数据结构的作用会发生周期性的变化: 活动进程突然变成
过期进程, 而过期进程变为活动进程, 调度程序简单志交换运行队列的active和expired字段的内容就可以完成这个变化.
下图:
系统中的每个可运行进程属于且只属于一个运行队列. 只要可运行进程保持在同一个运行队列中, 它就只可能在拥有该运行
队列的CPU上运行. 在某些情况下, 可运行进程会从一个运行队列迁移到另一个运行队列.
2. 进程描述符
进程描述符中包含几个与调度相关的字段
......
int prio 动态优先级
......
int static_prio 静态优先级
......
unsigned int time_lice 进程时间片中剩余时钏节拍数
......
unsigned long rt_priority 进程实时优先级
......
新进程被创建的时候, 父进程剩余节拍数被划分为两等分: 一份给父进程, 另一份给子进程. 这样可避免用户通过下面的方法获
得无限CPU时间: 父进程通过适当地调节速度, 创建一个运行相同代码的子进程, 并随后杀死自己, 子进程就可以总是在父进程
过期之前获得新的时间片. 这样, 进程就不能通过创建多个后代来霸占资源(除非它有给自己实时策略的特权)
如果父进程的时间片只剩下一个时钟节拍, 则强行把current->time_slice置为0, 从而耗尽父进程的时间片.
阅读(997) | 评论(0) | 转发(0) |