1.进程的三种理论基本状态
1)就绪(ready)状态
当进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行,进程这时的状态称为就绪状态。在一个系统中处于
就绪状态的进程可能有多个,通常将它们排成一个队列,称为就绪队列
2)执行状态
进程已获得CPU,其程序正在执行。在单处理机系统中,只有一个进程处于执行状态;在多处理机系统中,则有多个进程处于执行状态。
3)阻塞状态
正在执行的进程由于发生某事件而暂时无法继续执行时,便放弃处理机而处于暂停状态,亦即进程的执行受到阻塞,把这种暂停状态称为阻塞状态,
有时也称为等待状态或*状态。致使进程阻塞的典型事件有:请求I/O,申请缓冲空间等。通常将这种处于阻塞状态的进程也排成一个队列。
有的系统则根据阻塞原因的不同而把处于阻塞状态的进程排成多个队列。
2.linux进程状态 (state)剖析
我分析的源码版本:linux-2.6.34
linux内核通过task_struct(进程描述符)结构体来管理进程,这个结构体包含了一个进程所需的所有信息。它定义在linux-2.6.34\include\linux\sched.h文件中
关于进程状态,源码中的注释如下:
/*
* Task state bitmask. NOTE! These bits are also
* encoded in fs/proc/array.c: get_task_state().
*
* We have two separate sets of flags: task->state
* is about runnability, while task->exit_state are
* about the task exiting. Confusing, but this way
* modifying one set can't modify the other one by
* mistake.
*/
进程状态分为两类:struct_task中成员state(关于运行的状态)和exit_state(关于退出的状态)
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8
/* in tsk->exit_state */
#define EXIT_ZOMBIE 16
#define EXIT_DEAD 32
/* in tsk->state again */
#define TASK_DEAD 64
#define TASK_WAKEKILL 128
#define TASK_WAKING 256
#define TASK_STATE_MAX 512
TASK_RUNNING:表示进程要么正在执行,要么正要准备执行
处于这种状态的进程,要么正在运行、要么正准备运行。正在运行的进程就是当前进程(由current所指向的进程),而准备运行的进程只要得到CPU就可以立即投入运行,CPU是这些进程唯一等待的系统资源。系统中有一个运行队列(run_queue),用来容纳所有处于可运行状态的进程,调度程序执行时,从中选择一个进程投入运行。在后面我们讨论进程调度的时候,可以看到运行队列的作用。当前运行进程一直处于该队列中,也就是说,current总是指向运行队列中的某个元素,只是具体指向谁由调度程序决定。
TASK_INTERRUPTIBLE:E表示进程被阻塞(睡眠),直到某个条件变为真。条件一旦达成,进程的状态就被设置为TASK_RUNNING。
处于该状态的进程正在等待某个事件(event)或某个资源,它肯定位于系统中的某个等待队列(wait_queue)中。Linux中处于等待状态的进程分为两种:可中断的等待状态和不可中断的等待状态。处于可中断等待态的进程可以被信号唤醒,如果收到信号,该进程就从等待状态进入可运行状态,并且加入到运行队列中,等待被调度;而处于不可中断等待态的进程是因为硬件环境不能满足而等待,例如等待特定的系统资源,它任何情况下都不能被打断,只能用特定的方式来唤醒它,例如唤醒函数wake_up()等。
TASK_UNINTERRUPTIBLE:TASK_UNINTERRUPTIBLE的意义与TASK_INTERRUPTIBLE类似,除了不能通过接受一个信号来唤醒
__TASK_STOPPED:表示进程被停止执行
此时的进程暂时停止运行来接受某种特殊处理。通常当进程接收到SIGSTOP、SIGTSTP、SIGTTIN或 SIGTTOU信号后就处于这种状态。例如,正接受调试的进程就处于这种状态。
__TASK_TRACED:表示进程被debugger等进程监视
/* exit_state */
EXIT_ZOMBIE:表示进程的执行被终止,但是其父进程还没有使用wait()等系统调用来获知它的终止信息
进程虽然已经终止,但由于某种原因,父进程还没有执行wait()等系统调用,终止进程的信息也还没有回收。顾名思义,处于该状态的进程就是僵尸进程,这种进程实际上是系统中的垃圾,必须进行相应处理以释放其占用的资源。
EXIT_DEAD:表示进程的最终状态