打印本文 打印本文 关闭窗口 关闭窗口
Linux 2.4进程调度分析 6
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1568  更新时间:2009/4/22 20:45:51  文章录入:mintao  责任编辑:mintao

六. 其他核心应用的调度相关部分

系统中很多技术都和调度器相关,这里仅就其中几个稍作展开,并且不涉及该技术的细节,仅就其中与调度器相关的部分进行讨论,假定读者对于该技术有初步的了解。

1. IDLE进程

系统最初的引导进程(init_task)在引导结束后即成为cpu 0上的idle进程。在每个cpu上都有一个idle进程,正如上文所言,这些进程登记在init_tasks[]数组中,并可用idle_task()宏访问(见上"相关数据结构")。idle进程不进入就绪队列,系统稳定后,仅当就绪队列为空的时候idle进程才会被调度到。

init_task的task_struct是静态配置的,定义在[include/linux/sched.h]中的INIT_TASK()宏中,其中与调度相关的几个属性分别是:

  • state:TASK_RUNNING;
  • counter:10*HZ/100;i386上大约100ms
  • nice:0;缺省的优先级
  • policy:SCHED_OTHER;非实时进程
  • cpus_runnable:-1;全1,未在任何cpu上运行
  • cpus_allowed:-1;全1,可在任何cpu上运行

在smp_init()中(实际上是在[arch/i386/kernel/smpboot.c]中的smp_boot_cpus()中),init_task的processor属性被设为0,对应的schedule_data也设置好相应的值。在创建了一个核心线程用于执行init()函数之后([/init/main.c]rest_init()),init_task设置自己的need_resched等于1,然后调用cpu_idle()进入IDLE循环。

在cpu_idle()中,init_task的nice值被设为20(最低优先级),counter为-100(无意义的足够小),然后cpu_idle()进入无限循环:

/* 节选自[arch/i386/kernel/processs.c] cpu_idle() */

while (1) {

                    void (*idle)(void) = pm_idle;

                    if (!idle)

                               idle = default_idle;

                    while (!current->need_resched)

                               idle();

                    schedule();

                    check_pgt_cache();

}

 

初始化过程中第一次执行cpu_idle(),因need_resched为1,所以直接启动schedule()进行第一次调度。如上文所述,schedule()会清掉need_resched位,因此,之后本循环都将执行idle()函数,直至need_resched再被设置为非0(比如在reschedule_idle()中,见上"调度器工作时机")。

idle()函数有三种实现可能:

  • default_idle(),执行hlt指令;
  • poll_idle(),如果核心参数上定义了"idle=poll",则pm_idle会指向poll_idle(),它将need_resched设置为特殊的-1,然后反复循环直到need_resched不等于-1。因为poll_idle()采用更高效的指令,所以运行效率比default_idle()要高;
  • 电源管理相关的idle过程,例如APM和ACPI模块中定义的idle过程。

因为仅当就绪队列为空的时候才会调度到idle进程,所以,只有在系统完全空闲时才会执行check_pgt_cache()操作,清理页表缓存。

2. 进程创建

系统中除了init_task是手工创建的以外,其他进程,包括其他CPU上的idle进程都是通过do_fork()创建的,所不同的是

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口