进程状态及状态转换 我们首先,先来看一下最基本的状态一共有三个,运行态、 就绪态、等待态 那么运行态指的是这个进程已经拥有了CPU 并且在CPU上执行。 就绪态指的是进程已经具备了运行的条件 但是由于没有空闲的CPU,所以这个进程暂时还不能运行 打个比方就是说,万事俱备只欠CPU。 第三种状态呢我们把它称之为等待态,那么指的是这个进程 因为等某一个事件,而暂时不能运行 那么什么样的事件可以使得 进程处于等待态呢?比如说你要去读盘 一个进程要去到磁盘读数据在数据还没有读完之前,没有读到内存之前,这个进程暂时是不能运行的,因为它要之后的工作是要处理数据好,那么等待态还有其它的一些说法 这也是在学习操作系统的过程中,大家要关注的 一个名词会有多种说法,那么等待态呢,又称为阻塞态或者封锁态,或者睡眠态 这是进程的三种基本状态在进程运行过程中由于进程自身的进展,或者是一些外界条件的变化 进程的状态呢,会有改变 也就是说,从某一个状态进入到另外一个状态我们来看一下有哪些状态的转换 就绪态什么时候进入运行态呢? 就绪态进入运行态,是因为这个进程被调度程序选中了那么运行态什么时候 又回到了就绪态呢?一个正在运行的进程在两种情况下可能会回到就绪态 一个是它运行完了,分配给它的时间片所以它不能再继续运行了 它回到就绪态,等待下一个时间片的分配,或者是一个高优先级的进程,它进入了就绪态,因此 它会去抢占正在运行的这个进程 那么被抢占的这个进程呢,它也要回到就绪态 什么情况下,正在运行的进程会进入等待态呢?等待是有原因的 往往是当一个进程等待某个事件发生的时候 那么它暂时不能运行,而进入等待态,比如说它请求了一个操作系统的服务 啊,现在服务还没有结束,或者是它要用某个资源,这个资源不能使用还不能被使用,或者是它等待一个I/O的结果 也可能是 等待另外一个进程,给它发来消息,总之它 拿不到这个事件,等不到这个事件,这个进程就不能执行那么一旦事件发生了,那么 从等待态这个进程,就进入了什么呢?就绪态 继续准备上CPU,所以当事件发生的时候那么它就从等待态,进入了就绪态 这是三种基本状态,以及它们之间的状态转换。 这张图其实我们可以看到没有从就绪态进入等待态的这样一个转换 也没有,从等待态直接进入运行态的这么一个转换大家可以思考一下,为什么?除了 这三种基本状态之外呢,操作系统可能还有其它的一些 状态,那么这是状态的设计,就是操作系统在设计这个进程模型的时候,必须要首先考虑的问题 我们现在来看一下,另外两种 典型的状态,一个是创建态,一个是终止态 所谓创建态呢就是说已经完成了,创建一个进程的必要的工作 分配了PID,填写了PCB但是呢由于某种原因,这个进程 还不能够马上执行,操作系统没有许可它执行 那么原因当然可能是,由于现在系统资源有限,现在系统负载太大你不要暂时,暂时你不要运行,那么终止态呢,当然就是程序结束了,进程结束了 它进入了终止态,那么 在进入终止态之后呢,操作系统还要为这个进程做一些工作一项工作呢,是做一些数据统计工作 你用了多少CPU,你用了多少资源,那么你要做一些记录另外最重要的,就是要把你所申请的,所拿到的资源要收回来 因为你已经不再运行了,这个进程已经不再运行了,所以它的所有资源要收回那么这是两个,也是比较常见的状态 还有一个状态呢叫做挂起态 挂起态呢比较特殊,它往往指的是在操作系统当中,如果想进行一些负载调节的时候 那么可能会把一个,一些进程,把它送入这个状态 那么如果现在系统中进程太多那么CPU也忙不过来了,所以操作系统会把一部分进程,让它暂时不能运行但是它又不是等待,因为不是等待某个事件发生,所以就把它弄成一个特殊的状态,叫挂起态一旦进程进入了挂起态,操作系统会把它的内存空间呢收回来把这些内容,把它的进程的相关的内容,把它送到磁盘上保存起来 那么一旦,还继续让它运行,我们通常称之为激活,那么这个进程的内容,再从磁盘上读入内存就可以了所以呢,我们在三种基本状态之外呢,还可以为 一个进程设计这么三种不同的状态,好,我们来看一下 五状态模型,也就是增加了创建态和终止态创建完了进程之后,把它通过提交,进入了就绪态 通过调度就绪态进程,变成了运行态,运行过程中可能因为超时了等因素,那么从运行回到了就绪 如果运行的进程等待某个事件发生,那么就它变成了等待态当等待的事件发生了呢,它就又回到了就绪态 如果进程运行过程中结束了,那么就进入了终止态,这就是五状态模型的进程状态的转换我们可以看到,都有一些发生的条件,以及相应的操作 那么引入了,挂起态之后呢,那么那就变成了一个七状态模型我们来看一下七状态模型的,一个状态转换 。那么当系统的负载过重的时候,操作系统会把一部分就绪的进程,让它进入就绪挂起之后呢,可能在某个时候再把它激活但是这部分 内容呢,这部分的这个进程呢,可能还不够多,所以呢操作系统还会把一些处于阻塞态的进程把它 变成阻塞挂起,进一步减轻系统的负载。当然了,如果 条件允许再次激活它,可能在激活之前,等待的事件发生了,所以那么阻塞挂起的这个进程,可以直接进入什么呀?就绪挂起当然有的时候,也可能会出现 让一个正在运行的进程,当它正好下CPU的时候,把它直接送入到 就绪挂起的队列,那么这就是一个七状态的模型 在一个实际 操作系统当中,可能涉及不同的进程状态 同时不同的进程状态之间的转换,也有不同的条件和不同的操作 我们简单地看一下Linux的状态及状态转换Fork是创建了一个进程,变成就绪 通过调度,上了CPU。 可能等某个 条件,某个事件进入了睡眠态 当这个事件发生了,就又回到了就绪 如果正在运行的进程时间片到了就重新进入就绪队列 可能在运行过程中还会等其他的条件,就进入了另一种睡眠那大家可以看到,有两种睡眠状态 那么,它的区别呢主要是说,浅度睡眠在睡眠过程中会接收信号这是一种特定的通信机制 而深度睡眠的进程是不接收信号的这就是它们的区别,然后 正在运行的进程呢,可能因为调试,设定了断点所以它处于了一个叫作暂停状态,这也是跟调试有关系 那么暂停状态,然后以后接着执行,又进入就绪 正在执行的进程如果结束了,我们说终止了那么就进入了一个,我们说终止态,当然linux里头,把终止态称之为 僵尸态,僵尸态,其实就是进程终止了 那么,这是linux的状态的示意图。 所以我们可以看到 任何一个操作系统,它在设计 进程模型的时候呢,要确定有什么样的状态 确定状态之间的转换,在什么条件下转换 通过什么样的操作来促成这种转换 那么操作系统当中 有很多的进程,它们都处于不同的状态所以呢,需要按不同的状态把它们管理起来 因此,操作系统设计了一个若干个进程队列 为每一个类进程呢,建立一个或者多个队列也是可以的每个队列的元素呢,实际上就是PCB。 状态的改变,其实就是某个进程的PCB,从一个队列出队 然后,对在另一个队列里头入队的过程 也就是伴随着状态的改变,它的PCB从一个队列进入到另外一个队列。 我们来看一下这就是一个队列的 描述。那么这里头进程如果处于就绪态,那么就排一个队 那么就绪态通常我们看到是一个队列,其实在实际系统中,就绪态的这个进程可以排多个不同的队列 那么等待态有不同的原因所以呢,不同的原因等在不同的这个队列里头 根据等的事件不同,来等在不同的队列里头 所以我们可以看到,就是多个等待队列实际上呢,就是表示等待的事件不同。 就绪队列呢 也可以是多个,我们这里虽然画了一个,也可以是多个 那么在单CPU的情况下,由于 运行的进程只能有一个,所以我们就没有画出运行的队列 这里给出了一个五状态进程模型的队列模型我们可以看到,有一个就绪队列 那么创建好的进程通过许可进入就绪队列被调度程序选中上CPU,运行完了以后呢退出 如果运行的时间片到了,超时了,它就继续回到就绪队列 那么运行过程中如果等待某个事件,就进入到相应的等待事件的队列 当这个事件发生呢,就又回到了就绪队列 所以这是一个五状态进程模型当中的一个队列的模型