Chinaunix首页 | 论坛 | 博客
  • 博客访问: 917211
  • 博文数量: 119
  • 博客积分: 2493
  • 博客等级: 大尉
  • 技术积分: 2363
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-03 14:00
文章分类

全部博文(119)

文章存档

2013年(19)

2012年(100)

分类: LINUX

2012-08-03 16:51:33

一,前言
          最近想看看进程的调度,觉得2.6的调度比较复杂,很难下手,于是从2.4开始学习。
觉得学习“历史”是为了把握好“现在”和“未来”吧,2.6的调度器的设计都是针对2.4调度器
的不足而提出来的。
-------------------------------------------------------------------------------------
二,task_struct结构中关于调度字段的简介。(2.4内核中的)
       1,policy:调度策略。
            调度策略在2.4内核中有三种选择,SCHED_OTHER,该策略用来常规的分时调度,
针对的是普通进程,SCHED_FIFO,该策略用来先进先出申请运行,除非有更高优先级的
进程申请运行,不然它会运行至结束才让出CPU,针对的是实时进程。SCHED_RR,时间片
轮转调度,该进程调度下来后将被置于就绪队列的末尾,以保证其他实时进程有机会运行。
该策略也是针对实时进程。
     2,counter
        记录进程的时间片内还允许运行的时间。主要用老作为进程调度的依据。
     3,nice:优先级。
        该值决定了进程的优先级,它决定了counter的初值。
-------------------------------------------------------------------------------------
三,调度器是如何选择下一个要运行的进程的。

  1.  585 still_running_back:
  2.  586 list_for_each(tmp, &runqueue_head) {
  3.  587 p = list_entry(tmp, struct task_struct, run_list);
  4.  588 if (can_schedule(p, this_cpu)) {
  5.  589 int weight = goodness(p, this_cpu, prev->active_mm);
  6.  590 if (weight > c)
  7.  591 c = weight, next = p;
  8.  592 }
  9.  593 }
2.4内核中就使用了一个单就绪队列,也就是一个双向循环链表来组织的。示意图如下:
调度器先遍历该队列,然后计算其每个进程的“权值”,每个进程的“权值”就是代码中的
weight,该值是由进程的调度策略和进程的优先级计算出来的。计算过程也比较简单,可以
分析函数goodness,就觉得计算很简单。
对于实时进程(调度策略为SCHED_FIFO或SCHED_RR):
weight = 1000 + p->rt_prioroty
对于普通进程(调度策略未SCHED_OTHER)。
weight = p->counter.
-----------------------------------------------------------------------------------
四,调度器选出下一个要执行的进程后的的切换工作。
      1,进程地址空间的切换。我们都知道,每个进程都有3GB的用户空间,进程切换,
进程的地址空间也会随之切换。页表也会随之切换。假如现在要调度的是一个内核线程
该怎么办呢?内核线程是内核态的,他没有用户空间。2.4的处理是“借用”前一个进程
的地址空间。
  1. switch_mm(oldmm,mm,next,this_cpu);
内核中使用该函数实现了进程地址空间的切换。
      2,进程上下文切换。
         该切换主要是切换进程的堆栈,使用的是几句很经典的汇编实现的。
实现的函数:
  1. switch_to(prev,next,prev);
-------------------------------------------------------------------------------------
五,2.4内核调度器的缺点。
    1,单就绪队列问题。调度算法与系统进程的数量呈相关,队列越长,选择下一个要执行的
进程的时间就越长,因为要遍历这个就绪队列,还有一些计算。
    2,多处理器问题。多个处理器使用一个就绪队列,将就绪队列为临界资源,各个处理器要
等待才能进入就绪队列,使得多处理器的效率很低。
    3,内核态的不可抢占问题。只要一个进程进入内核,即使一个很紧迫的任务到来,也只能
等待,只有那个进程返回用户态,紧迫的任务才能得到相应。

-------------------------------------------------------------------------------------

参考:


           
阅读(1583) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~