CPU调度策略&linux 0.11的schedule实现--OS

CPU调度策略

如何设计调度算法?
这个算法应满足

  • 尽快结束任务:周转时间(从任务进入到任务结束)短
  • 用户操作尽快响应:相应时间(从操作发生到响应)短
  • 系统内耗时间少:吞吐量(完成的任务量)

总原则:系统专注于任务执行,又能合理调配任务…

两种基础的CPU调度策略

  1. 短作业优先

短作业优先策略,主要是为了减少周转时间

基本思路: 运行时间短的进程优先执行,但是可能会造成饥饿现象

  1. 轮转策略

轮转策略,减少相应时间

基本思路: 给每一个进程设置一个时间片,当时间片用完后,就切换进程,总的响应时间最大为n*时间片,只要设置合理的时间片大小,就能有效的减少响应随时间。

两种基本的策略都无法解决前台与后台的矛盾,前台需要减少响应时间,但是后台需要减少周转时间,如何才能既设置好合理的调度算法?

一个实际的schedule函数

void Schedule(void)
{
    while(1)
    {
        c=-1;
        next=0;
        i=NR_TASKS;
        p = &task[NR_TASKS];
        while(--i)  // 找出最大的counter
        {
            if((*p->state == TASK_RUNNING && (*p)->counter>c))
            {
                c = (*p)->counter;
                next = i;
            }
        }
        if(c) //找到最大的counter;
            break;
        for(p=&LAST_TASK; p>&FIRST_TASK; --p)  //将counter除2并加上初值(*p)->priority
        {
            (*p)->counter = ((*p)->counter>>1)+(*p)->priority;
        }
    }
    switch_to(next);
}

void do_timer(...)  //在kernel/sched.c中
{
    if(--current->counter>0)
        return;
    current->counter=0;
    schedule();
}

_timer_interrupt: //在kernel/system_call.s中
...
call _do_timer

void sched_init(void)
{
    set_intr_gate(0x20, &timer_interrupt);
}

counter的作用

  1. 作为时间片,每一次轮转后都会进行一次do_timer中断,减一
  2. 作为优先级,我们找到最大的counter时,它是被当作优先级来看待的

这段代码的妙处

    for(p=&LAST_TASK; p>&FIRST_TASK; --p)  //将counter除2并加上初值(*p)->priority
    {
        (*p)->counter = ((*p)->counter>>1)+(*p)->priority;
    }
  • 当时间片用完时,能够更新时间片的大小
  • 将counter除2加初值,意味着那些正在执行IO任务的进程的counter会不断增大,而不断增大意味着优先级在不断提高,我们知道,IO任务往往跟前台的进程相关,因为用户跟计算机交互大多数涉及IO如键盘输入等,这样就能保证前台进程的响应时间短。
  • 后台进程一直按照counter进行轮转,这样短作业进程肯定比长作业进程优先完成,这样就能保证周转时间短

综上所述,该算法既能满足前台进程对响应时间要求短的需求还满足了后台进程对周转时间短的要求,也就是糅合了前面提到的两种基本CPU调度算法,而且用一个counter就完成了这个任务,可以说是太强了。

(*p)->counter = (*p)->counter>>1 + (*p)->priority是否会造成IO进程的counter趋于无穷大?

c(t) = c(t-1)/2 + p
c(0) = p

我们计算一下

c(1) = p/2 + p = 3/2p
c(2) = 3/4p + p = 7/4p
c(3) = 7/8p + p

我们将其展开

c(1) = p + p/2
c(2) = p + p/2 + p/4
c(3) = p + p/2 + p/4 + p/8

显然,我们学过高数都知道

c(n) = p + (p/2+p/4+p/8+...+p/n) < 2p

所以,最大的响应时间也不会超过2np

你可能感兴趣的:(CPU调度策略&linux 0.11的schedule实现--OS)