【Linux 进程】进程的状态管理
一、进程状态简介
一个进程的生命周期可以划分为一组状态,这些状态刻画了整个进程。进程状态即体现一个进程的生命 状态。 进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型 中,进程状态分为三个基本状态,即运行态,就绪态,阻塞态。在五态模型中,进程分为新建态、终止 态,运行态,就绪态,阻塞态。
二、进程状态分类
1. 三态模型
一个进程从创建而产生至撤销而消亡的整个生命期间,有时占有处理器执行,有时虽可运行但分不 到处理器、有时虽有空闲处理器但因等待某个事件的发生而无法执行,这一切都说明进程和程序不 相同,它是活动的且有状态变化的,这可以用一组状态加以刻画。为了便于管理进程,一般来说, 按进程在执行过程中的不同情况至少要定义三种不同的进程状态: (1)运行(running)态:进程占有处理器正在运行。 (2)就绪(ready)态:进程具备运行条件,等待系统分配处理器以便运行。 (3)等待(wait)态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某 个事件的完成。 通常,一个进程在创建后将处于就绪状态。每个进程在执行过程中,任意时刻当且仅当处于上述三 种状态之一。同时,在一个进程执行过程中,它的状态将会发生改变。引起进程状态转换的具体原 因如下: (1)运行态一一等待态:等待使用资源或某事件发生,如等待外设传输;等待人工干预。 (2)等待态一一就绪态:资源得到满足或某事件己经发生,如外设传输结束;人工干预完成。 (3)运行态一一就绪态:运行时间片到,或出现有更高优先权进程。 (4)就绪态一一运行态:CPU空闲时被调度选中一个就绪进程执行。
2. 五态模型
在一个实际的系统里,进程的状态及其转换比上面叙述的复杂一些,例如,引入专门的新建态(new) 和终止态(exit )。
引入新建态和终止态对于进程管理来说是非常有用的。新建态对应于进程刚刚被创建的状态,创建1 个进程要通过两个步骤,首先,是为一个新进程创建必要的管理信息;然后,让该进程进入就绪 态。此时进程将处于新建态,它并没有被提交执行,而是在等待操作系统完成创建进程的必要操 作。必须指出的是,操作系统有时将根据系统性能或主存容量的限制推迟新建态进程的提交。 类似地,进程的终止也要通过两个步骤,首先,是等待操作系统进行善后;然后,退出主存。当一 个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终 止权的进程所终结,它将进入终止态。进入终止态的进程以后不再执行,但依然保留在操作系统中 等待善后。一旦其他进程完成了对终止态进程的信息抽取之后,操作系统将删除该进程。
引起进程 状态转换的具体原因如下: (1)NULL一一新建态:执行1个程序,创建一个子进程。 (2)新建态一一就绪态:当操作系统完成了进程创建的必要操作,并且当前系统的性能和内存的容 量均允许。 (3)运行态一一终止态:当1个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系 统所终结,或是被其他有终止权的进程所终结。 (4)终止态一一NULL:完成善后操作。
3. 经常使用的进程状态
(1)运行态(TASK_RUNNING) : 此时进程或者正在运行,或者准备运行,就绪或者正在进行都属于 运行态
(2)睡眠态(TASK_SLEEP): 此时进程在等待一个事件的发生或某种系统资源 可中断的睡眠 (TASK_INTERRUPT) : 可以被信号唤醒或者等待事件或者资源就绪 不可中断的睡眠(TASK_UNTERRUPT) : 只能等待特定的事件或者资源就绪。
(3)停止态(TASK_STOPPED) : 进程暂停接受某种处理。例如:gdb调试断点信息处理。
(4)僵尸态(TASK_ZOMBIE):进程已经结束但是还没有释放进程资源。
三、补充
(1)进程是程序执行的过程。
(2)程序就是静态的,是一些指令的结合,保存在磁盘中。
(3)而程序一旦运行,就产生了进程,操作系统就会为进程分配资源,进程是分配资源最小单元。
(4)时间片的轮转
优先级并不代表一定能抢占到资源,也不是优先级高的先于优先级低的任务先执行。
竞争CPU资源,谁竞争到了谁执行。
每一个时间片内只有一个进程进行。
五态模型及进程状态之间的转换
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
printf("请输入一个数字\n");
int num;
scanf("%d,&num");
while(1){
}
return 0;
}
状态变化:
(1)由就绪态---》运行态
(2)运行态---》可中断的睡眠态
(3)可中断的睡眠态---》运行态
(4)按下ctrl+c,进程由信号产生中断,进入僵尸态
子进程的代码: fork的数之后的代码就是子进程的代码
父子进程并发执行,子进程从fork()函数之后开始执行
为什么两次显示结果有差异?
如果父进程在子进程打印之前结束,则会回到终瑞命令后继续执行子进程
如果子进程的打印语句在父进程结束之前执行,则会在回到终端命令前执行完毕
父子进程的执行顺序由操作系统调度算法决定的,不是由程序本身决定
《3》子进程会拷贝父进程地址空间的内容包括缓冲区、文件描述符等