内核 -进程调度的细节
进程调度(2)-细节
以下以 linux 内核为例讨论进程调度的细节:
在 UNIX 进程的生存期间,它可能处于几种状态中的一种。下面是它的主
要状态:
TASK_RUNNING 仅当进程处于这一状态时,调度程序才认为它是
可以运行的。它等同于上一节图 1 中的可运行状态。
TASK_INTERRUPTIBALE 处于这一状态的进程在休眠之中。但
是,如果它接受一个信号,将使他转为 TASK_RUNNING 状态。这相当
于图中的挂起状态。
TASK_UNINTERRUPTIBLE 除了不能用信号改变进程的状态外,
类似于上一个状态。通常需要用 wake_uup()函数来唤醒休眠中的进
程。wake_up()函数用来实现图中的转换 5。
LINUX 系统中每个进程用 task_struct 结构来表示。其中包括进程运行环
境的许多细节。在下列文件中说明了这一结构:
/usr/src/linux/include/linux/sched.h
当进程刚建立时候,由内核 do-fork()函数将这一结构动态地分配给进
程。do_fork()函数包含在下列的文件中;
/usr/src/linux/fork.c
task_struct 的成分之一称为 counter。它在进程调度中起重要作用。处
于 TASR_RUNNING 状态的进程的 counter 的值越高,当调度程序运行
时就越可能被选为下一次执行的进程。counter 的值一般在 0-70 之
间。在某些情况下也可能超出这个值。
在下列 4 种主要情况下,要求在 CPU 上运行的进程放弃对 CPU 的控制,
使其他进程能运行:
1.当进程要求为它进行输入/输出操作时(如磁盘的存取操
作),而这一操作需要一定的时间才能完成。在这种情况
下,即使时间延迟只有几毫秒也要重新进行调度。