L14 CPU调度策略
- FIFO
- Priority
不同场景如何设定不同的策略
- 面向用户的
- 面向进程的
要求
- 尽快结束任务: 周转时间(从任务进入到任务结束)短
- 系统内耗时间少: 吞吐量(完成的任务量)
用户操作尽快响应: 响应时间(从操作发生到响应)短 :::info 前台任务和后台任务的关注点不同
前台任务关注响应时间,
后台任务关注周转时间 ::: IO约束型任务和CPU约束型任务有各自的特点
-
几种常见的CPU调度算法
FCFS
最质朴直接的想法:先来先服务
这种方式十分简单,但是会造成一个问题:可能周转时间会比较长;
:::tips 对于第一种调度: :::SJF
缩短调度时间的质朴的想法:短作业优先;
把CPU区间较短的作业放在前面,那么后面任务等待的时间肯定会降低
但是这样也会带来问题:后面的作业的响应时间可能会过长RR
响应时间和周转时间同时存在,怎么办
直观想法: 定义前台任务和后台任务两队列,前台RR,后台SJF,只有前台任务没有时才调度后台任务
but会出现很多问题(前台一直有任务,后台任务就不会执行)
- 后台任务优先级动态升高,但后台任务(用SJF调度)一旦执行,
L15 一个实际的schedule函数
void Schedule(void) //在kernel/sched.c中
{
while(1){
c=-1; next=0; i=NR_TASKS;//Linux0.11中,PCB以数组的形式存储,NR_TASKS指向数组末尾
p=&task[NR_TASKS];
while(--i){
if((*p->state == TASK_RUNNING&&(*p)->counter>c)
c=(*p)->counter, next=i;
}
if(c) break; //找到了最大的counter
for(p=&LAST_TASK;p>&FIRST_TASK;--p)
(*p)->counter=((*p)->counter>>1)+(*p)->priority;
}//时间片轮转?
switch_to(next);
}
conter作用1:时间片轮转
void do_timer(...) //在kernel/sched.c中
{
if((--current->counter>0) return;//每次时间片--,为零就切换
current->counter=0;
schedule();
}
_timer_interrupt: //在kernel/system_call.s中
...
call _do_timer //每次时钟中断都会调用,查看时间片是否为0
void sched_init(void) {
set_intr_gate(0x20, &timer_interrupt)
};
conter作用2:优先级动态调整:IO操作的优先级会生高(阻塞队列中待得越久,conter越会升高)