进程间的状态切换
在任意时刻下,通常只有一个进程可以被加载到计算机的CPU上运行。
三状态模型
任何一个进程在它的生命周期内都会处于下面三种状态,使用这三种状态可以简单描述运行在计算机上的进程之间的状态切换,进程的一生都处在这三种状态间相互转换。
- 运行态(Running):指该进程正在被CPU调度运行。
- 就绪态(Ready):指该进程满足被CPU调度的所有条件但此时并没有被调度执行。
- 阻塞态(Blocked):指该进程正在等待某事件的发生之后才可以继续被CPU调度运行。
三状态模型之间的切换
CPU在调度进程时,只会去操作系统维护的处于就绪态的进程PCB链表中调度,所以三状态模型之间的切换只有4种切换方式:
- 就绪态—>运行态:当操作系统的调度程序从就绪态的链表中调度一个进程时,该进程的进程状态就会被切换为运行态,与此同时CPU即会开始运行此进程。
- 运行态—>就绪态:当一个进程的时间片到达,CPU必须去调度下一个进程时,此时处于运行态的进程的进程状态就会被切换为就绪态并重新进入操作系统就绪态的进程链表。
- 运行态—>阻塞态:当CPU正在运行一个进程时,该进程此时需要等待一个时间的完成才能继续运行(例如:程序的I/O流 …),这时操作系统就会将该进程的进程状态切换为阻塞状态,直到进程所需要的等待事件完成。
- 阻塞态—>就绪态:进程从运行态直接切换为阻塞态,当进程所需要的事件完成之后,操作系统不会直接将该进程的状态切换为运行态,而是将该进程的状态切换为就绪态,等待CPU的调度。
Linux操作系统的进程状态转换
Linux操作系统的进程
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
从Linux源码中可以看出,Linux下有7中进程状态:
- R运行状态(Running):处于运行状态的进程并不带表一定就正在被CPU调度运行,它包括了正在被CPU运行的进程和可以被CPU调度运行的程序,也就是说改状态包含了三状态模型中的就绪态和运行态。
- S睡眠状态(Sleeping):处于改状态的进程表示该进程正在等待某时间的完成,通常也称为可中断睡眠状态,该状态属于三状态模型中的阻塞态。
- D磁盘休眠状态(disk sleep):该状态也叫做不可中断睡眠状态,处于该状态的进程通常都在等待I/O操作的结束,该状态也属于三状态模型中的阻塞态。
- T停止状态(stopped):我们可以通过向进程发送SIGSTOP信号让目标进程处于停止状态,通过向处于停止状态的进程发送SIGCON信号让目标进程继续运行,该状态也属于三状态模型中的阻塞态。
- t追踪停止状态(tracing stop):
- X死亡状态(dead):该状态只是一个返回状态,不会在任务列表中见到,该状态属于退出状态。
- Z僵尸状态(zombie):当一个进程退出,但它的父进程并没有去收回该进程的信息时,该进程所处的状态叫做僵尸状态,该状态属于退出状态。
Linux系统进程状态间的切换
创建一个新进程,操作系统会为该新进程创建一个空白PCB(task_struct),用来存储该进程的各项信息。