进程的引入
程序的顺序执行及其特征
通常,一个程序的编制一般都是输入、处理(计算)、输出的循环,即循环执行输入、处理(计算)、输出的代码。
程序顺序执行时的特征:
-
顺序性。程序所规定的每个动作都在上一个动作结束后才开始。
-
封闭性。程序在运行时,独占全机资源,因而机内各资源的状态只有本程序才能改变它。
-
可再现性。当机器在同一数据集上重复执行同一程序时,每次执行结果相同。即程序的执行结果与执行速度无关。
-
确定性。程序无论从头到尾不停地运行还是“停停走走”地执行,都不会影响最终结果。
程序的并发执行及其特征
把一个输入、处理(计算)、输出的程序分解成三部分:输入模块I、计算模块C、输出模块P,由于这三个程序模块所使用的资源互不冲突,因此可以使这三个程序模块并发执行。
程序并发执行时的特征:程序执行的间断性、程序执行失去封闭性、程序执行结果的不可再现性、资源共享、程序与计算不再一一对应。
进程的概念
在多道程序系统中,程序的执行出现“走走停停”的新状态,把程序执行的每一个新状态称作一个进程
。进程是程序在某一数据集上的一次运行过程。进程与程序是有区别的:
-
程序是静态概念,本身可以作为一种软件资源保存;而进程是为了执行程序产生的,是程序在某一数据集上的一次执行过程,是动态概念,它有一定的生命期,是动态地产生和消亡的。
-
进程是一个能独立运行的单位,能与其他进程并发执行,进程是作为资源申请和调度单位存在的;而通常的程序段不能作为一个独立运行的单位。
-
程序和进程无一一对应关系。一方面一个程序可由多个进程公用;另一方面,一个进程在活动中又可顺序地执行若干个程序。
CPU有两种状态:用户进程使用CPU(用户态或目态)、系统进程使用CPU(系统态或核心态或管态)
CPU是用户进程与系统进程交替切换、分时使用来完成进程的推进的。
程序或作业的完成是以进程的方式参与运行的。
进程的执行是走走停停的。
进程的基本特征:
-
动态性
。进程是程序的执行过程,它有生有亡,有活动有停顿,可以处于不同的状态。 -
并发性
。多个进程的实体能存在于同一内存中,在一段时间内都得到运行。这样就使得一个进程的程序与其它进程的程序并发执行了。 -
独立性
。进程实体是一个能独立运行的基本单位,同时也是系统中独立获得资源和独立调度的基本单位。凡未建立进程的程序都不能作为一个独立的单位参与进行。 -
异步性
。指进程按各自独立的、不可预知的速度向前推进,或者说,进程按异步方式运行。这个特征将导致程序执行的不可再现性。 -
结构性
。为了描述和记录进程的动态变化,并使之能正确运行,为每个程序设置一个数据结构,即进程控制块。一个进程实体由程序段、数据段、栈和进程控制块这四部分组成,也称为进程映像。
进程状态模型
最简单的进程运行模型——两态模型
进程要么正在执行,要么没有执行。一个进程就只有两种状态:运行(Running)状态和非运行(Not-running)状态。
# 两状态进程模型
每个进程必须以某种方式(状态、优先级等)代表,以便操作系统能够对其进行跟踪。
进程的基本状态模型——三态模型
进程最基本、最核心的三种状态:
-
运行态
(Running)。指当前进程已分配到CPU,它的程序正在处理机上执行时的状态。处于这种状态的进程个数不能大于CPU的数目。 -
就绪态
(Ready)。指进程已具备运行条件,但因为其他进程正占用CPU,所以暂时不能运行而等待分配CPU的状态。 -
阻塞态
(Blocked)。指进程因等待某种事情发生而暂时不能运行的状态。
对于进程的三种基本状态,可以有四种转换关系:
-
运行状态→阻塞状态。当一个进程正在CPU上运行的时候,它可能需要进行一些输入/输出操作,如从用户那里输入一些数据。但是相对于高速运行的CPU而言,用户敲键盘的动作是很慢的,因此操作系统不会允许这个进程继续占用CPU,在CPU里一直等待下去,而是把它变成内存或外存的阻塞状态,然后调度其他就绪进程去继续占用CPU运行。
-
阻塞状态→就绪状态。一个进程处于阻塞状态的原因是它正在等待某个事件的发生,如等待数据的输入,那么当这个事件发生以后,该进程就已经具备了继续运行的条件,所以操作系统就会把它从阻塞状态转换成就绪状态。
-
就绪状态→运行状态。由CPU调度程序来完成的,进程调度程序会根据一定的调度策略从就绪队列中选择一个最合适的进程来继续占用CPU运行。
-
运行状态→就绪状态。当一个进程在CPU上正常运行时,如果操作系统的调度程序认为它已经连续运行了足够长的时间(如给定的时间片到),就会暂停它的运行,把它从运行状态变为就绪状态,然后再调度其他进程来运行。这样每个进程都能得到运行的机会,因此比较公平。
在一个进程的运行过程中,如果没有涉及输入/输出操作,也没有涉及与其他进程之间的同步关系,那么它就会不停地在运行和就绪这两个状态之间来回转换,就这样不断地循环,一直到该进程运行结束为止。而且这种转换完全是自动进行的,是由操作系统,确切地说,是由CPU调度程序来完成的。而对于进程本身,或者说,当编写这个程序的时候,并不会意识到这些,还以为它一直处于运行状态。
进程的五态模型
在上述进程三种基本状态的基础上,又增加了两种状态:创建状态和退出状态。因为进程在创建和退出时操作系统还有许多工作要做,设立这两种状态便于操作系统对进程进行管理。
-
创建状态
(New)。进程正在创建过程中,还不能运行。操作系统在创建进程时,要为这个进程分配一个进程表,填写相关内容、为进程分配进程组,连接进程的父子关系、为进程分配所需的资源、为进程建立地址空间,填写有关管理内存的表格、加载程序等。当就绪队列接纳新创建的进程时,操作系统把处于创建状态的进程移入就绪队列,此时进程从创建状态转换为就绪状态。 -
退出状态
(Exit)。进程正常或异常结束,操作系统首先要将该进程从运行状态中移出,使之成为一个不可能再运行的进程,相应地使进程处于退出状态,并收回其所占的资源。此时系统并不立即撤销它,而是暂时留在系统中,以便让其他相关进程从该退出进程的进程表中收集有关信息。当进程已经完成了预期的任务,或者发生某事件,如出现地址越界、非法指令等错误而被异常终止时,进程将由运行状态转换为退出状态。
进程的七态模型
又增加了挂起状态:就绪挂起(Ready Suspend)、阻塞挂起(Block Suspend)。
# 进程的七态模型
引入挂起状态的原因:内外存对换的需要、用户调试程序的需要、进程间断执行的需要、系统安全的需要、实时系统中调节负载的需要。
当内存空间紧张时,可以将进程从内存移出到外存,即挂起进程;相反,当内存空间宽裕时,将移至外存的进程再移回内存,即解挂进程。新增的进程状态转换关系有以下几种:
-
阻塞→阻塞挂起。当内存紧张时会引起这种状态的转换。将处于阻塞状态的进程挂起(从内存移到外存),是为了腾出更多的内存空间给新创建的进程或就绪的进程。
-
就绪→就绪挂起。当挂起一些阻塞的进程仍然不能满足内存的需要,或者当有高优先级阻塞的进程和低优先级就绪的进程时,系统会选择首先挂起低优先级就绪的进程,因为系统认为应该让高优先级的进程尽快完成。
-
运行→就绪挂起。在抢占式分时系统中,当高优先级阻塞挂起的进程因事件出现而进入就绪挂起状态时,如果此时内存空间不够,系统可能将正在运行的进程状态转化为就绪挂起状态。
-
就绪挂起→就绪。当系统没有了就绪的进程,或者内存空间充裕,或者当就绪挂起的进程的优先级高于就绪的进程时,会引起在外存就绪挂起的进程解挂后进入内存就绪状态。
-
阻塞挂起→阻塞。当进程释放了足够的内存空间时,系统会将高优先级阻塞挂起的进程解挂,使该进程从外存移到内存。
-
阻塞挂起→就绪挂起。处于阻塞挂起的进程当等待的事件已经完成,而内存空间还是不足时,系统会将这个阻塞挂起的进程转入就绪挂起状态。
进程描述
进程表
用于维护和管理系统中活动的各个进程,进程必须以某种组织形式链接起来,以便于定位和查找。进程表也是操作系统用于控制和管理进程的主要依据和结构。进程表中的每一进程都有地址指针指向该进程的进程映像空间。进程映像是一个进程的具体物理组成,是程序、数据、栈和进程控制块的集合。进程映像的位置依赖于使用的存储管理方法。
每一个进程都有一个也只有一个进程控制块(PCB),进程控制块是操作系统用于记录和描述进程状态及有关信息的数据结构,也是操作系统控制和管理进程的主要依据,它包括了进程执行时的情况,以及进程让出处理器后所处的状态、断点等信息。进程控制块的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位和一个能与其他进程并发执行的进程。或者说,操作系统是根据PCB来对并发执行的进程进行控制和管理的。
当系统创建一个新进程时,就为它建立一个PCB,进程结束时又回收其PCB,进程也随之消亡。PCB可以被操作系统中的多个模块读取或修改,如被调度程序、资源分配程序、中断处理程序以及监督和分析程序等读取或修改。因为PCB经常被系统访问,尤其是被运行频率很高的进程调度访问,故PCB应常驻内存。系统将所有的PCB组织成若干个链表(或队列),存放在操作系统中专门开辟的PCB区。
# 进程控制块的主要内容
标识符信息:进程标识符(进程名/进程号)、用户标识(用户名/用户号)、家族联系(父进程/子进程)
处理机状态信息:通用寄存器、指令计数器、程序状态字、用户指针
进程调度信息:进程状态、进程优先数、等待原因、调度算法参数等
进程控制信息:程序和数据地址、进程同步和通信机制、资源清单、链接指针、访问权限、打开的文件
进程控制块的组织
为了对所有进程进行有效的管理,常将各个进程的PCB用适当的方式组织起来。一般来说,有以下三种方式:
-
线性方式。存在的主要问题是限定了系统中同时存在的进程的最大数目,当很多用户同时上机时,会造成无法为用户创建新进程的情况。更严重的缺点是,在执行CPU调度时,为选择合理的进程投入运行,经常要对整个表进行扫描,降低了调度效率。
-
链接方式。按照各进程的不同状态分别将它们的PCB放在不同的队列中。
-
索引方式。利用索引表记载不同状态进程的PCB地址。系状态相同的进程的PCB组织在同一索引表中,每个索引表的表目中存放一个PCB地址。各索引表在内存的起始地址放在专用的指针单元中。
进程控制
从计算机系统安全和保护的角度出发,在进行计算机体系结构设计时,处理机的执行模式一般分为两种,内核模式(或核心态、系统态、管态)和用户模式(用户态、算态、目态)。显然,处理机在运行期间需要在内核模式和用户模式之间切换。进程切换与处理机执行模式的切换是两个不同的概念。在多道系统中,进程切换的时机通常在事件中断时,无论是何种事件的中断,系统都将进入内核模式,执行系统的中断处理。至于进程是否在中断发生时进行切换,与系统的调度方式和策略有关。
内核
是操作系统的控制和协调中心,由它组织、启动和协调系统中的各种活动。内核部分常驻内存,以提高系统运行效率,并对其加以特殊的保护。
-
进程管理:进程派生和调度、进程创建和终止、进程同步及对进程间通信的支持、PCB的管理。
-
内存管理:进程地址空间的分配/回收、交换、页/段的管理
-
I/O管理:设备驱动、缓冲区管理、进程I/O设备、控制器、通道的分配与回收
-
支持功能:中断处理、时钟管理(其中包括中断)、监视
内核中有些功能由原语操作实现。原语
本身也是由若干个指令构成的,用于完成一定功能的一个过程;它与一般过程/函数的区别在于,它是原子操作。所谓原子操作就是不可分割的操作,要么不做,要么全做。原语可分为两类:
-
机器指令级原语。执行期间不允许中断,在操作系统中它是一个不可分割的基本单位。
-
功能级原语。作为原语的程序段不允许并发执行。
这两类原语都在系统态下执行,且都是为了完成某个系统管理所需要的功能和被高层软件所调用。利用原语这一特征,通常把进程控制类的程序段做成原语。用于进程控制的原语有创建原语、撤销原语、阻塞原语、唤醒原语、进程同步原语等。中断处理是操作系统内核中一项非常重要的功能,是系统中进程状态转换和进程切换的基础和核心,也是操作系统的“灵魂”。
进程图
(Process Graph)是描述进程族系关系的有向树。进程可以创建子进程,子进程创建子进程,便形成了进程族谱结构——进程图。子进程可以继承父进程所拥有的资源,父进程也可以动态地撤销子进程。在子进程终止时,归还从父进程得到的资源。在父进程终止时,将同时撤销所有的子进程。为了标记进程这种族谱关系,在进程控制表PCB中设有进程族谱表项,用于指示其父进程和子进程。
进程创建与终止
# 进程创建
给新进程分配一个唯一的进程标识号PID,从系统空闲的PCB结构中摘出一个PCB表。
为新进程分配所需的资源,包括程序、数据和工作区。
初始化PCB,包括进程名、用户名、父进程标识符、进程优先级、处理机状态(就绪)、程序执行地址、栈指针等。
将新进程插入就绪队列。
一个进程派生新进程后,有以下两种可能的执行方式:
-
创建者和被创建者并发执行
-
创建者等待它的某个或全部子进程终止
# 进程终止
根据被终止进程的标识号,从系统的PCB表中检索该进程的PCB,若该进程正在运行,则立即终止它的运行。
回收该进程的全部资源(包括程序空间、外部设备等)
若它还有子进程,则同时终止子进程,回收其全部资源。
将该进程的PCB从所在的结构中移出(暂存在系统其他空间),由其他进程搜集信息和进程善后工作,进入完成状态。
待系统将该进程有关的一切工作完成后,收回该进程的PCB,插入空闲的PCB队列中,该进程也就消失。
进程阻塞与唤醒
引起进程阻塞和唤醒的事件:启动I/O操作、请求系统资源、同步约束、服务进程无服务。
# 进程阻塞
立即停止当前进程的运行,保护CPU现场到该进程的PCB现场保护区。
将进程执行状态修改为阻塞状态,插入相应的阻塞队列中。
转进程调度程序,重新选择一个就绪状态的进程投入运行。
唤醒进程即可被系统进程调用,也可被事件发生进程调用。调用唤醒原语的进程称为唤醒进程。唤醒原语既可以返回原调用程序,也可以转向进程调度,选择一个合适的进程。
# 进程唤醒
将相关的阻塞进程从阻塞队列摘出。
修改阻塞状态为就绪状态,并插入就绪队列中。
调度程序进行新的调度,或继续恢复原当前进程。
进程挂起与解挂
# 进程挂起
找到需要挂起进程的PCB,将其从相应队列摘出。
将其空间归还系统(由系统存储管理模块负责回收)。
判断被挂起进程的状态,如为阻塞状态,则将其状态修改为静止阻塞;如为就绪状态,则修改为静止就绪。
申请交换区(外存)空间,将部分或全部进程映像写到交换区,并将交换区地址记入PCB中。
如被挂起的进程为当前进程,则转进程调度。
当出现解挂事件时,若进程映像驻留在交换区,当内存空间满足时,则系统利用解挂原语将指定的进程解挂。解挂的过程与挂起的进程基本是一个对应相反的过程。
(最近更新:2019年09月18日)