操作系统之进程的描述与控制——进程的基本状态及其转移、PCB内容及其作用

2019-07-14 08:34发布

进程的描述与控制

进程的描述

程序的顺序执行和并发执行

顺序执行的特点

  1. 顺序性:每一操作都在下一操作开始前结束,严格按照顺序;
  2. 封闭性:程序在封闭环境下执行,程序运行时占全机资源,资源的状态只有该程序才能改变,一旦程序开始执行,结果不受外界影响;
  3. 可再现性:初始状态和执行环境相同的条件下,程序反复执行,结果不变;

并发执行的特点

  1. 间断性:临界资源的访问以及程序之间由于合作而形成的限制关系使得并发执行的程序具有间断性;
  2. 非封闭性:并发程序共享系统资源,各个程序都有可能使资源状态的改变,从而改变其他程序的执行环境;
  3. 不可再现性:因为程序的执行失去了封闭性,所以程序的执行环境也会改变,故其结果不在具有可再现性(执行环境无法保证不变);

进程的定义和特征

进程定义

为了使程序可以并发执行(有意义的并发执行),并且对并发执行的程序加以描述和控制,人们引入进程的概念;为了使参与并发执行的程序可以独立运行,操作系统定义了一种数据结构来描述、控制和管理进程,即进程控制块(Process Control Block, PCB)。这样,由程序段、数据、PCB三部分构成了进程实体。 这样,我们就可以把进程定义为:进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位;

进程的特征

  1. 动态性:它由创建而产生,因调度而执行,由撤销而死亡。进程实体有一定的生命周期,而程序这只是一组有序指令的集合,本身不具有活动的含义,属于静态的;
  2. 并发性:是指多个进程实体存在于内存中,且能在一段时间里同时运行;
  3. 独立性:是指进程实体是一个能独立运行、独立获得资源和独立接收调度的基本单位。未建立PCB的程序无法作为独立单位参与运行;
  4. 异步性:是指进程按异步方式运行,OS通过同步机制来保证异步执行的进程其并发执行的结果是可再现的。

进程的三种基本状态及转移

由于并发执行的进程共享临界资源,致使他们在运行过程中呈现间断性特点,所以进程在其生命周期内具有多种状态。以下是三种常见的基本状态:

三种基本状态

  1. 就绪状态:进程已经处于准备执行的状态,它获得了除CPU以外的其他资源,只要获得处理机即可运行;操作系统通常将所有就绪的进程组织为一个队列,即就绪队列;
  2. 执行状态:进程获得CPU而得以执行;单处理机中,某一时刻只有一个进程处于执行状态;多处理机中某一时刻有多个进程处于执行状态;
  3. 阻塞状态:执行状态的进程由于发生某事件(如IO请求、申请缓冲区失败)而暂时无法执行的状态,此时通过进程调度,OS将处理机分配给另一个处于就绪状态的进程。系统通常将所有处于阻塞状态的进程组织为一个队列,即阻塞队列。有时为了提高调度效率,减少队列操作的开销,系统会根据阻塞原因,设置多个阻塞队列;

三种基本状态间的转换

  1. 就绪状态->执行状态:处于就绪状态的进程因获得处理机而得以运行,其状态也由就绪状态改为相应的运行状态;
  2. 执行状态->就绪状态:处于执行状态的进程因其时间片已经用完而失去处理机,从执行状态进入就绪状态;
  3. 执行状态->阻塞状态:处于执行状态的进程由于请求资源(常见的资源如内存空间、文件、IO设备等)失败而无法继续运行,从执行状态进入阻塞状态;
  4. 阻塞状态->就绪状态:处于阻塞状态的进程由于所请求的资源可以使用,从阻塞状态转入就绪状态;
  5. 执行走向终止;(这是一个进程的终点线,其实也算得上一个状态转移,只是这里的终止更多的是一种结果,不同于下面的终止状态)
值得注意的是,并不能从阻塞状态直接进入执行状态,也不能从就绪状态直接进入阻塞状态;即阻塞状态是一个单入单出的状态;

创建和终止状态

引入创建和终止状态是为了满足进程控制块对数据及操作的完整性要求以及增强管理的灵活性。
创建状态
  1. 进程由于创建而产生,进程的创建一般涉及到以下步骤:首先申请空的PCB(由父进程或者操作系统申请),然后向PCB中填充用于控制和管理进程的信息;再向进程分配运行时必要的资源;最后将该进程转入就绪状态并置入就绪队列;但是,如果进程所需要的资源无法满足,自然也就不能接受调度而运行,此时的状态就称为创建状态;当其所需的资源被满足时,即可从创建状态转入就绪状态;
  2. 引入创建状态的原因:
    1. 为了保证进程的调度必须在创建工作完成后进行,以确保对进程控制块的操作完整性;
    2. 引入创建状态也有利于增强管理上的灵活性:OS可以根据系统性能和资源状况,推迟新进程的提交;
终止状态
  1. 进程的终止通常要经过两个阶段:首先是操作系统进行善后工作,回收该进程占用的资源;然后将PCB清零,并归还系统;
  2. 进程终止的常见原因:
    1. 自然到达终止点;
    2. 出现无法克服的错误;
    3. 被操作系统终止;
    4. 被其他有权限的进程终止。
    进入终止状态的进程无法再运行,但是系统还会保留一个该进程的记录,其中保存一些状态码和计时统计信息以供其他进程收集。当其他进程收集完毕后,操作系统将执行第二步,清空并归还PCB。
引入了创建和终止状态的进程状态转移如下:
  1. 前4种转移情况同三种状态的转换;
  2. 创建->就绪:进程所需要的资源(除了处理机)全部满足,进程可以接受调度(数据是完备的);
  3. 执行->释放:进程因上面提到的原因而进入终止状态,等待操作系统的回收;

挂起操作和进程状态的转移

挂起操作的引入

  1. 引入挂起操作的原因:
    1. 终端用户需要在程序运行期间观察或者修改程序,需要使之处于静止状态;
    2. 父进程需要考察和修改该子进程,或者协调各个子进程之间的活动;
    3. 负荷调节的需要,当系统中的工作负担较重,可能影响到对实时任务的控制时,系统需要将一些不重要的进程挂起以保证系统的正常运行;
    4. 操作系统的需要,操作系统有时需要挂起检查运行中资源的使用情况。
    所谓的挂起操作,就是让该进程处于静止状态,即从物理位置上来看,静止的进程其相关信息将被置放在外存。与挂起操作相对应的操作就是激活啦~

五种状态间的转移

引入挂起和激活操作后,原来的就绪和阻塞状态一分为二:活动就绪和静止就绪以及活动阻塞和静止阻塞,相应的状态转换也变为:
  1. 活动就绪->静止就绪:处于活动就绪状态的进程因挂起而转入静止就绪状态;
  2. 活动就绪->执行:处于活动就绪状态的进程因调度而执行;
  3. 静止就绪->活动就绪:处于静止就绪状态的进程因激活而转入活动就绪状态;
  4. 活动阻塞->静止阻塞:处于活动阻塞状态的进程由于挂起操作而进入静止阻塞状态;
  5. 活动阻塞->活动就绪:处于活动阻塞状态的进程由于所请求的资源得以满足而进入活动就绪状态;
  6. 静止阻塞->活动阻塞:处于静止阻塞状态的进程由于激活而进入活动阻塞状态;
  7. 静止阻塞->静止就绪:处于静止阻塞状态的进程由于所请求的资源得以满足而进入静止就绪状态;
  8. 执行->活动阻塞:执行状态的进程由于所请求的资源无法满足而进入活动阻塞状态;
  9. 执行->静止就绪:执行状态的进程由于挂起操作而进入静止就绪状态;
  10. 执行->活动就绪:执行状态的进程由于时间片用完而进入活动就绪状态;
  11. 执行->终止:从执行到死亡;
从以上来看,静止就绪是一个单出口的状态:静止就绪状态只能通过激活操作进入活动就绪状态;执行状态是一个单入口的状态:即只能由活动就绪状态通过调度而进入执行状态;同样,终止状态也是一个单入口状态

七种状态间的转移

所谓七种状态的转移是指在五种转移基础上引入创建和终止两种状态;新增的两种转移如下:
  1. 创建->活动就绪:在当前系统的性能和内存的容量均允许的情况下,完成对进程创建的必要操作后,进程处于活动就绪状态;
  2. 创建->静止就绪:由于当前系统的性能和内存容量情况不允许新建进程获得全部资源(主要是不给它分配内存空间),新创建的进程被安置在外存而不参与调度,此时创建过程尚未结束;

进程管理中的数据结构

操作系统使用数据结构的重要性

一方面,为了便于对计算机中各类资源的使用和管理,OS将其抽象为各种数据结构以及提供一组对资源进行操作的命令,用户便可利用这些数据结构和操作命令实现对计算机系统的操作而无需了解其实现的具体细节; 另一方面,特别是在多用户共享资源的情况下,操作系统作为计算机资源的管理者,需要记录和查询计算机系统中各类资源的使用情况,OS对这些信息的维护和组织也是通过各种数据结构来实现的; 操作系统中用于管理控制的数据结构通常分为四类(按资源种类分类):内存表、文件表、设备表和进程表,其中进程表就是我们所说的PCB。这些数据结构通常包含对资源的标志、描述、状态等信息以及相应的指针;

PCB的作用

PCB记录了操作系统所需的,用于描述和管理进程的全部信息,是操作系统中最重要的记录型数据结构;它的作用有:
  1. 作为可独立运行的基本单位的标志。进程是资源分配和可独立运行的最小单位(在未引入线程之前是这样的),而创建一个进程的实质是创建一个PCB,撤销一个进程的实质是销毁一个PCB,即系统通过PCB感知进程的存在。事实上,PCB已成为进程存在的唯一标记。
  2. 实现间断性运行方式。并发执行的程序具有间断性,也正是因为间断性使其结果具有不可再现性,故一般的程序不能有意义地进行并发,引入进程的目的之一就是让程序实现有意义的并发执行,而之所以可以这么做,就是因为操作系统使用PCB来保留进程执行时的CPU现场,使得程序在恢复执行时,其运行环境是一致的。其实,作为传统意义上的静态程序,就是因为它不具有保护或者保存自己运行现场的能力而无法保证其运行结果的可再现性。从而失去运行的意义。
  3. 提供进程管理所需要的信息。当进程因调度而运行时,系统会通过PCB中的内容,找到该进程所需程序和数据在内存或者外存的地址;当创建一个进程的时候,系统通过PCB中的资源清单为该进程分配所需要的资源,并记录这些资源的使用情况。即在进程的整个生命周期内,操作系统总是根据PCB实施对进程的管理;
  4. 提供进程调度所需要的信息。只有处于就绪状态的进程可以被调度执行,所以需要在PCB中记录进程当前的状态;同时在PCB中还需要记录调度算法要用的信息,比如,进程的优先级、进程的运行时间和等待时间等;
  5. 实现进程间通信和同步。进程同步是为了实现诸多进程的协调运行,PCB为进程之间的通信提供相应的数据结构,以便实现进程同步等功能。
进程管理是针对一个进程而言的,而进程调度是针对许多进程而言的;所以进程管理重在对进程所拥有的资源的管理;进程调度则偏重于对进程状态的管理;以前总是混淆3和4,觉得记录状态难道不是为了管理吗?其实,两者都是管理,但是管理的高度和目的不同。知识必具有个性,才配说是自己的!

PCB中的信息

  1. 进程标记符:通常有两种进程标记符,一种是面向用户的外部标记符,由用户提供,便于用户对进程的访问;另一种是面向系统的内部标记符,用系统产生,唯一标记一个进程,通常全是数字。 为了描述进程的家族关系,还应设置父进程以及子进程的相关标记;
  2. 处理机状态:处理机状态信息也称为处理机上下文,通常有处理机的各种寄存器的内容组成,这些寄存器包括:通用寄存器(用于暂存信息)、指令计数器(指示下一条指令的位置)、程序状态字(状态信息,如条件码,执行方式、终端屏蔽标记等)、用户栈指针(栈,用于存放过程和系统调用参数和调用地址,栈顶指针指向栈的顶部)等。当进程被切换时,需要将这些信息记录到PCB中,以便该进程在恢复执行时能够还原以前的环境;
  3. 进程调度信息:这些信息包括:
    1. 进程状态;
    2. 进程优先级;
    3. 进程调度所需要的其他信息,如等待时间、已执行时间等,这和系统所使用的调度算法有关;
    4. 事件,即进程的阻塞原因;
  4. 进程控制信息:这些信息包括:
    1. 程序和数据的地址;
    2. 进程同步和通信机制所需要的数据结构,如消息队列、信号量;
    3. 资源清单,包括全部所需要的资源清单和已经获得的资源清单;
    4. 链接指针:指向下一个PCB的地址;

PCB的组织方式

进程控制块的组织形式通常有三种:
  1. 线性方式:所有PCB都组织在一张线性表中,实现简单,开销小,但是查找效率低,适合进程数目不多的系统;
  2. 链式方式:即把具有相同状态的进程的PCB分别通过链接指针连接成一个队列,这样就可以形成就绪队列、阻塞队列和空白队列等,这些队列当然可以是优先权队列了。也可以将阻塞队列按原因的不同分别组织成多个队列,以便查找;
  3. 索引方式:将相同状态的进程的PCB的地址存储在相应的索引表(该索引表常使用顺序表结构)里,然后相应的PCB指针指向索引表; 索引方式和链式方式不同的是,链式存储中,系统使用PCB指针指向PCB队列地址;索引方式中,系统使用索引表的指针;使用索引表应该是为了提高查询和删除PCB的效率吧,平时使用索引表使用的少,没有直观感受;

进程控制

操作系统内核

现代操作系统一般将操作系统分为多个层次,将OS按不同功能分别设置到不同层次,常把一些同计算机硬件关联紧密(如中断处理程序)、各种设备的驱动程序以及运行频率较高的模块(时钟管理、进程调度和其他公用模块)都放置到紧靠硬件的的软件层次中,将它们常驻内存,即为操作系统的内核;这种安排有两个好处:一是便于对这些软件进行保护,防止遭到其他应用程序的破坏,另一个是提高它们的运行效率; 与上面对应的是,处理机的执行状态通常也分为两种:系统态,也称为管态;拥有较高的权限,可执行一切命令,可访问所有寄存器,传统OS即运行于系统态;用户态,也称为目态。在权限、可执行命令范围、可访问的寄存器等方面均弱于系统态; 不同规模和类型的操作系统内核,它们包含的功能有差异,但是总体上来说都包含:支撑功能和资源管理功能;

支撑功能

支撑功能是供给OS其他模块使用的功能,以支撑其他模块的运行,其中基本的三种支撑功能为:中断处理、时钟管理、原语操作;
  1. 中断处理 中断处理是操作系统内核最基本的功能,是整个操作系统得以运行的基础,操作系统许多功能,如各种类型的系统调用、键盘命令输入、进程调度、设备驱动等都依赖于中断处理; 通常为了减少处理机的等待时间,提高程序执行的并发性,内核在对终端进行有限处理后,便转入相应进程,由这些进程继续完成后面的处理。
  2. 时钟管理 时钟管理是操作系统内核中的一项基本功能,在时间片轮转调度中,当一个进程的时间片用完时,由时钟管理产生一个终端信号,促使调度程序进行调度;在实时系统中对于截止时间的管理以及批处理系统中的最长运行时间的管理无不需要时钟管理模块的支持;
  3. 原语操作 原语操作,通常由若干条语句组成,这些语句要么全部执行,要么全不执行(就是quan bu 执行),原语在执行过程中不允许被打断。原语操作在系统态进行,常驻内存;

资源管理功能

内核的资源管理功能,也就是对常见的三种计算机资源的管理(进程、内存、设备的管理),没问题,这里少了对文件的管理,可能文件管理的重要程度还不至于将其放入到操作系统内核吧
  1. 进程管理 包括进程的调度与分派、进程的创建和撤销以及用于实现进程同步和通信的原语操作都将其放到操作系统内核,以提高OS性能;
  2. 存储器管理 存储器管理软件的运行频率也较高,主要涉及的功能有:逻辑内存地址到物理地址的映射、内存的分配和回收、内存的保护等,将其放到操作系统内核的主要原因是提高存储器的运行效率;
  3. 设备管理 设备管理通常和硬件关系紧密,因此放置到内核。这类软件主要包括:各类设备的驱动程序、用于缓和CPU和IO设备速度不匹配的缓冲管理、用于实现设备分配和设备独立性功能的模块;

进程的创建

进程的层次关系以及进程图

  1. 在OS中允许一个进程A创建另一个进程B,A称为B的父进程;B称为A的子进;由于子进程可以继续创建子进程,于是便形成一个进程的层次结构;
  2. 关于父进程和子进程,有以下几个关系:
    1. 子进程可以继承父进程的所有资源,包括打开的文件、申请的缓存;
    2. 当子进程被撤销时,需要将这些资源还给父进程;
    3. 当父进程被撤销时,其所有子进程都需要撤销;父进程不能拒绝子进程的继承权;
  3. 通常使用一个有向树来表示这种层次关系;这棵树也叫作进程图;
值得注意的是,windows系统中并没有这种层次关系,当一个进程创建了另一个进程时,父进程会获得一个子进程的句柄,即获得对该进程的控制权,但是该句柄是可以传递的,于是Windows系统中,进程的关系不再是层次关系,而是是否获得句柄、控制与被控制的关系;

进程的创建及其原因

  1. 引起进程创建的原因:
    1. 用户登录:在分时系统中,用户通过终端登入时,系统将为该用户创建一个进程,并将其插入到就绪队列中;
    2. 作业调度:在多道批处理系统中,当作业调度程序按照一定的算法调度到某个作业是,便将其装入内存,为其创建进程;
    3. 提供服务:运行中的用户程序提出某项要求时,系统将创建相应进程来为用户提供服务;
    4. 应用请求:由用户进程自己创建进程,以便使新进程和创建者进程并发运行来完成任务;
  2. 进程的创建过程:
    1. 申请空的PCB,为该进程分配唯一的内部标记,从PCB集合中获得一个空的PCB;
    2. 为新进程分配所需的资源,这里的资源包括物理资源和逻辑资源,如内存、文件、IO设备、处理机等,这些资源或者从操作系统处获得,或者从父进程处获得,不管从哪里获得,都需要告诉操作系统或者父进程;
    3. 初始化PCB。PCB的初始化包括:
      1. 初始化标记信息:将系统分配的内部标记和父进程标记填入PCB中;
      2. 初始化处理机状态,使程序计数器指向程序的入口地址,使栈顶指针指向栈顶;
      3. 初始化处理机控制信息:将进程的状态设为就绪或者静止就绪,对于优先级,通常设置为默认值,如果用户没做设定;
      4. 如果就绪队列可以接受新进程便将其插入就绪队列;

进程终止及其原因

进程终止有三种情况:正常结束、异常结束、外界干预
  1. 正常结束:进程应该有一个用于表示进程已经结束的指示以通知系统进程结束;
  2. 异常结束:是指进程在运行时发生了某种异常事件,使得程序无法继续运行下去,常见的事件有:
    1. 越界错:数组越界等;
    2. 保护错:试图访问不允许访问的资源;
    3. 非法指令:试图执行一条不存在的指令,常是因为程序错误地转入数据区,错把数据当做了指令;
    4. 特权指令:试图执行一条只允许OS执行的指令;
    5. 运行超时:程序的执行时间超过了允许的最大值;
    6. 等待超时:程序的等待时间超过允许的最大值;
    7. 算数错误:比如发生了除0等;
  3. 外界干预:进程应外界要求而终止运行,常见的情况有:
    1. 操作员或者操作系统的干预,如系统发生死锁,操作员或者操作系统需要终止某些进程以使系统恢复;
    2. 父进程的要求;
    3. 因父进程终止,其所有子进程也需要终止;
进程的终止过程:
  1. 根据被终止的进程标记符,从PCB集合中查找该进程所对应的PCB;
  2. 若该进程处于执行状态,则立即终止其执行,并置调度标志为真,用于指示该进程终止后应重新进行调度;
  3. 若该进程还有子孙进程,将其所有子孙进程全部终止;
  4. 归还进程所拥有的资源,从哪里来的,还回哪里去;
  5. 将该PCB从所在链表移出,等待其他程序来收集相关信息;

进程的阻塞和唤醒

进程的阻塞

进程阻塞的常见原因有:
  1. 向系统请求共享资源失败;
  2. 等待某种操作的完成,常见的是等待IO操作完成;
  3. 新数据尚未到达,该进程无法继续运行,常见于多个进程相互合作完成一项工作时;
  4. 等待新任务的到达,在某些系统中,特别是在网络环境下的OS,往往设定一些特殊的进程,每当这种进程完成任务后就把自己阻塞起来,等待新任务的到来来唤醒自己;
阻塞是一种主动行为,即当发生上面的情况时,进程主动阻塞自己,之后调度程序进行重新调度;

进程的唤醒

进程的唤醒,首先将被阻塞的进程从阻塞队列中移出,将其PCB的状态改为就绪,然后将该PCB插入到就绪队列中;值得注意的是,阻塞和唤醒是一对作用刚好相反的原语操作,必须成对出现;否则,阻塞进程将无法被唤醒而继续执行;

进程的挂起和激活

进程的挂起,首先根据进程当前的状态,设置相应的状态(状态转换见“7种状态间的转移”);然后将PCB移入相应的队列中;为了用户或者系统考察该进程的运行状况,会把该PCB复制到指定的内存区域;如果被挂起的进程正在运行,则会转向调度程序重新调度; 进程的激活,首先根据进程的当前状态,设置相应的状态;然后将PCB移入相应的队列中;如果是采用抢占调度策略,则每当有静止就绪进程被激活而插入到就绪队列中时,由调度程序将激活进程的优先级同当前进程的优先级进行比较,如果被激活的进程有较高的优先级,则会剥夺当前进程的执行,将处理机交给被激活的进程;