目的
为了对进程从产生到消亡的整个过程进行跟踪和描述,就需要定义各种进程的各种状态并制定相应的状态转换策略,以此来控制进程的运行。
粗略分类
运行态:进程占用 CPU,并在 CPU 上运行;就绪态:进程已经具备运行条件,但是 CPU 还没有分配过来;阻塞态:进程因等待某件事发生而暂时不能运行;当然理论上上述三种状态之间转换分为六种情况;
运行 → 就绪:这是有调度引起的,主要是进程占用 CPU 的时间已耗尽。就绪 → 运行:当前运行的进程的时间片用完,调度就从就绪队列中选择合适的进程分配给 CPU。运行 → 阻塞:发生了 I/O 请求或等待某件事的发生。阻塞 → 就绪:进程所等待的事件发生,就进入就绪队列。
以上4种情况可以相互正常转换,不是还有两种情况吗?
阻塞 → 运行:即使给阻塞进程分配 CPU,也无法执行,操作系统进行调度时不会从阻塞队列进行挑选,其调度的选择对象为就绪队列。就绪 → 阻塞:因为就绪态根本就没有执行,何来进入阻塞态?
详细分类
现在知道了进程的三种基本状态,但是在操作系统具体现实中,设计者可以根据实际情况设置不同的状态,这样以来就出现了以下几种状态:
可运行态:运行态和就绪态的合并,表示进程正在运行或准备运行,Linux 中使用 TASK_RUNNING 宏表示此状态。浅度睡眠态:进程正在睡眠(被阻塞),等待资源到来是唤醒,也可以通过其他进程信号或时钟中断唤醒,进入运行队列。Linux 使用 TASK_INTERRUPTIBLE 宏表示此状态。深度睡眠态:其和浅度睡眠基本类似,但有一点就是不可其他进程信号或时钟中断唤醒。Linux 使用 TASK_UNINTERRUPTIBLE 宏表示此状态。暂停状态:进程暂停执行接受某种处理。如正在接受调试的进程处于这种状态,Linux 使用 TASK_STOPPED 宏表示此状态。僵死状态:进程已经结束但未释放 PCB,Linux 使用 TASK_ZOMBIE 宏表示此状态。
我们可以来看下以上宏在内核中的定义:
#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#define TASK_STATE_TO_CHAR_STR "RSDTtZXxKW"
LINUX进程间状态转换和内核调用图
(SAW:Game Over!)
如果觉得《Linux 进程状态详解》对你有帮助,请点赞、收藏,并留下你的观点哦!