计算机操作系统-第二章 进程的描述与控制 上——进程

2.1 前趋图和程序执行

2.1.1 前趋图

  • 所谓前趋图(precedence graph),是指一个有向无环图(directed acyclic graph,DAG),它用于描述进程之间执行的先后顺序。图中的每个节点均可用于表示一个进程或一段程序,甚至是一条语句,节点间的有向边则表示两个节点之间所存在的偏序(partial order)或前趋关系(precedence relation)
  • 程序之间的前趋关系可用“→”来表示。如果Pi和Pj间存在着前趋关系,则可将它们写成 (Pi,Pj)∈→ ,也可写成Pi→Pj,表示在Pj开始执行之前Pi必须执行完成。此时称Pi是Pj的直接前趋,而称Pj是Pi的直接后继。在前趋图中,把没有前趋的节点称为初始节点(initial node),把没有后继的节点称为终止节点(final node)。此外,每个节点还具有一个权重(weight),用于表示该节点所含有的程序量或程序的执行时间。在图2-2(a)所示的无循环的前趋图中,存在着如下前趋关系:
    • P1 → P2,P1 → P3,P1 → P4,P2 → P5,P3 → P5,P4 → P6,P4 → P7,P5 → P8,P6 → P8,P7 → P9,P8→ P9。
    • 上述关系还可表示为:
      • P={P1,P2,P3,P4,P5,P6,P7,P8,P9}
        → ={(P1,P2),(P1,P3),(P1,P4),(P2,P5),(P3,P5),(P4,P6),(P4,P7),(P5,P8),(P6,P8),(P7,P9),(P8,P9)}。
        在这里插入图片描述
  • 应当注意,前趋图中是不允许有循环的,否则必然会产生无法实现的前趋关系。例如,在图2-2(b)所示的有循环的前趋图中,就存在着循环。它一方面要求在S3开始执行之前S2必须完成,另一方面又要求在S2开始执行之前S3必须完成,显然,这种关系(即S2→S3,S3→S2)是不可能实现的。

2.1.2 程序顺序执行

  1. 程序的顺序执行
    • 通常,一个程序由若干个程序段组成,每个程序段负责完成特定的功能,且它们都需要按照某种先后次序被顺序运行,仅当前一程序段运行完成后,才会运行后一程序段。
      例如,在进行计算时,应先运行输入程序,用于输入用户的程序和数据;然后运行计算程序,对所输入的数据进行计算;最后才会运行打印程序,打印计算结果。我们用节点来代表各程序段的操作(在图2-3中用圆圈表示不同节点),其中I代表输入操作,C代表计算操作,P代表打印操作,箭头指示操作的先后次序。这样,上述的3个程序段的操作间所存在的前趋关系即可表示为:Ii→Ci→Pi,其执行的先后顺序可用图2-3(a)所示的前趋图来描述。
      在这里插入图片描述
    • 需要说明的是,即使是一个程序段,也可能存在执行顺序问题。例如,下面给出了一个包含3条语句的程序段。
      S1: a ∶=x+y ;
      S2: b ∶=a-5 ;
      S3: c ∶=b+1 ;
      • 其中,语句S2必须在语句S1(即a被赋值)后才能执行,语句S3也只能在语句S2(即b被赋值)后才能执行,因此,3条语句存在着前趋关系:S1→S2→S3,应按图2-3(b)所示的前趋关系顺序执行。
  2. 程序顺序执行时的特征
    顺序性:处理机会严格按照程序所规定的顺序执行语句,即每个操作都必须在下个操作开始之前结束;
    封闭性:程序在封闭的环境下运行,即程序运行时独占全机资源,只有本程序才能改变资源的状态(除初始状态外),程序一旦开始执行,其执行结果便不会再受外界因素影响;
    可再现性:只要程序执行时的环境和初始条件相同,当程序重复执行时,不论它是从头到尾不停顿地执行,还是“停停走走”地执行,都可获得相同的结果。程序顺序执行时的这种特性,为程序员检测和校正程序的错误带来了很大的方便。

2.1.3 程序并发执行

程序顺序执行时,虽然可以给程序员带来方便,但是系统资源的利用率却是极其低下的。为此,在系统中引入了多道程序技术,使程序或程序段间能并发执行。然而,并非所有的程序都能并发执行。事实上,只有不存在前趋关系的程序才有可能并发执行,否则无法并发执行。

  1. 程序的并发执行
    • 在图2-3中的输入程序、计算程序和打印程序三者之间,存在着Ii→Ci→Pi这样的前趋关系,以至对于一个作业而言,输入、计算和打印这三个程序段必须顺序执行。但是当需要处理一批作业(而非一个)时,每个作业的输入、计算和打印程序段的执行情况如图2-4所示。输入程序(I1)输入第一次数据后,在由计算程序(C1)对该数据进行计算的同时,输入程序(I2)可再输入第二次数据,从而使第一个计算程序(C1)可与第二个输入程序(I2)并发执行。事实上,正是由于C1和I2之间并不存在前趋关系,因此它们之间可以并发执行。一般来说,输入程序(Ii+1)在输入第i+1次数据时,计算程序(Ci)可能正在对输入程序(Ii)的第i次输入的数据进行计算,而打印程序(Pi-1)可能正在打印计算程序Ci-1的计算结果。
      在这里插入图片描述
    • 从图2-4中可以看出,存在前趋关系Ii→Ci,Ii→Ii+1,Ci→Pi,Ci→Ci+1,Pi→Pi+1,而在Ii+1和Ci以及Pi-1之间,不存在前趋关系,它们可以并发执行。
    • 对于具有下述4条语句的程序段:
      S1: a ∶=x+2;
      S2: b ∶=y+4;
      S3: c ∶=a+b;
      S4: d ∶=c+b;
      • 可画出图2-5所示的前趋关系。从图2-5中可以看出:S3必须在a和b被赋值后方能执行;S4必须在S3之后方能执行;但S1和S2则可以并发执行,因为它们彼此互不依赖。
        在这里插入图片描述
  2. 程序并发执行时的特征
    在引入程序间的并发执行功能后,虽然提高了系统吞吐量和资源利用率,但是由于它们共享系统资源,以及为完成同一任务而相互合作,这些并发执行的程序之间必将形成相互制约关系,这会给程序并发执行带来新的特征,介绍如下。
    • (1)间断性。程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,这些并发执行的程序之间形成了相互制约关系。例如,图2-4中的I、C和P是三个相互合作的程序,当计算程序Ci-1完成计算后,如果输入程序Ii尚未完成数据输入,则计算程序Ci就无法进行数据处理,此时必须暂停执行。只有当致使程序暂停的因素消失后(如Ii已完成数据输入),计算程序Ci才可恢复执行。由此可见,相互制约关系将导致并发程序具有“执行—暂停—执行”这种间断性的活动规律。

    • (2)失去封闭性。当系统中存在多个可以并发执行的程序时,系统中的各种资源将为它们所共享,而这些资源的状态也会由这些程序来改变,致使其中任一程序在执行时,其执行环境必然会受到其他程序的影响。例如,当处理机已被分配给某个进程执行时,其他程序必须等待。显然,程序的执行失去了封闭性。

    • (3)不可再现性。程序在并发执行时,失去封闭性会导致其失去可再现性。例如,有两个循环程序A和B,它们共享一个变量N。程序A每执行一次时,都要执行N = N + 1操作;程序B每执行一次时,都要执行Print(N)操作,然后再将N置成“0”。程序A和B以不同的速度运行。这样,可能出现下述3种情况(假定某一时刻变量N的值为n)。

      • ①若[ N = N + 1 ]在[ Print(N)和N = 0 ]之前执行,则各次操作对应的N值分别为n+1、n+1、0。
      • ②若[ N = N + 1 ]在[ Print(N)和N = 0 ]之后执行,则各次操作对应的N值分别为n、0、1。
      • ③若[ N = N + 1 ]在[ Print(N)和N = 0 ]之间执行,则各次操作对应的N值分别为n、n+1、0。

      上述情况说明,程序在并发执行时,由于失去了封闭性,其计算结果必将与并发程序的执行速度有关,这使程序的执行失去了可再现性。换言之,程序经过多次执行后,虽然多次执行时的环境和初始条件相同,但得到的结果却各不相同。

2.2 进程的描述

2.2.1 进程的定义与特征

1. 进程的定义

  • 为了使程序可以并发执行,并且可以对并发执行的程序加以描述和控制,人们在OS中引入了“进程”这一概念
  • 为了使参与并发执行的每个程序(含数据)都能独立地运行,在OS中必须为之配置一个专门的数据结构,称之为进程控制块(process control block,PCB)。系统利用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。
  • 由程序段、相关的数据段和PCB这3部分便构成了进程实体(又称为进程映像),简称为进程,例如,所谓创建进程,实质上是指创建进程的PCB;而撤销进程,实质上是指撤销进程的PCB。进程是动态的,进程实体(进程映像)是静态的。进程实体反应了进程在某一时刻的状态
  • 对于进程,从不同的角度可以给出不同的定义,其中较典型的定义有以下3种。
    (1)进程是程序的一次执行。
    (2)进程是一个程序及其数据在处理机上顺序执行时所发生的活动。
    (3)进程是具有独立功能的程序在一个数据集上执行的过程,它是系统进行资源分配和调度的一个独立单位。
  • 在引入进程的概念后,我们可以把传统OS中的进程定义为:“进程是程序的执行过程,是系统进行资源分配和调度的一个独立单位”。

2. 进程的特征

进程和程序是两个截然不同的概念,进程除了具有程序所没有的PCB外,还具有以下特征。

  • (1)动态性。进程的实质是程序的执行过程,因此,动态性就是进程最基本的特征。动态性还表现在:进程由创建而产生,由调度而执行,由撤销而消亡。由此可见,进程有一定的生命期,而程序则只是一组有序指令的集合,并存放于某种介质上,其本身并不具有活动的含义,因而是静态的
  • (2)并发性,是指多个进程共存于内存中,且能在一段时间内同时执行。引入进程也正是为了使进程能和其他进程并发执行。因此,并发性是进程的另一个重要特征,同时也成为了OS的重要特征;而程序(未建立PCB)是不能参与并发执行的。
  • (3)独立性。在传统OS中,独立性是指进程是一个能够独立运行、独立获得资源、独立接受调度的基本单位(引入线程后不是接收调度的基本的单位)。凡未建立PCB的程序都不能作为一个独立的单位参与并发执行。
  • (4)异步性,是指进程是按异步方式运行的,即按各自独立的、不可预知的速度向前推进。正是这一特征才导致传统意义上的程序若参与并发执行,则会使其结果不可再现。为了使进程在并发执行时虽具有异步性,但仍能保证进程并发执行的结果是可再现的,在OS中引入了进程的概念,并且配置了相应的进程同步机制。
  • 进程和程序的区别
    • 进程是程序的一个实例,
      是程序的一次执行。
    • 进程是活动的,
      程序是静态的。
    • 程序是进程的代码部分。
    • 进程在内存中,
      程序在外存中。
      在这里插入图片描述

2.2.2 进程的基本状态与转换

1. 进程的 3 种基本状态

  • (1)就绪(ready)状态,是指进程已处于准备好执行的状态,即进程已分配到除CPU以外的所有必要资源后,只要再获得CPU,便可立即执行。如果系统中有许多处于就绪状态的进程,则通常会将它们按一定的策略(如优先级策略)排成一个队列,称该队列为就绪队列
  • (2)执行(running)状态,是指进程获得CPU后其程序“正在执行”这一状态。对任何一个时刻而言,在单处理机系统中,只有一个进程处于执行状态,而在多处理机系统中,则可能会有多个进程处于执行状态。
  • (3)阻塞(block)状态。正在执行的进程由于发生某事件(如I/O请求、申请缓冲区失败等)而暂时无法继续执行,即指进程的执行受到了阻塞。此时会引发进程调度,OS会把处理机分配给另一个就绪进程,而让受阻进程处于暂停状态,一般将这种暂停状态称为阻塞状态,有时也称为等待状态或封锁状态。通常系统会将处于阻塞状态的进程排成一个队列,称该队列为阻塞队列。实际上,在较大的系统中,为了减少阻塞队列操作开销,提高系统效率,根据阻塞原因的不同,会设置多个阻塞队列。

2. 进程 3 种基本状态间的转换

进程在运行过程中,会经常发生状态的转换。例如,处于就绪状态的进程,在调度程序为之分配处理机之后便可执行,相应地,其状态就会由就绪转变为执行;正在执行的进程(当前进程),如果因分配给它的时间片已完而被剥夺处理机暂停执行时,其状态便会由执行转变为就绪;如果因发生某事件而致使当前进程的执行受阻(例如进程访问某临界资源而该资源又正在被其他进程访问),使之无法继续执行,则该进程状态将由执行转变为阻塞。
在这里插入图片描述

3. 创建状态和终止状态

为了满足进程控制块对数据与操作的完整性要求以及增强管理的灵活性,通常会在系统中为进程引入另外两种常见的状态:创建状态和终止状态。

  • (1)创建状态
    如前所述,进程是由创建或新建产生的。创建一个进程是一个很复杂的过程,一般要通过多个步骤才能完成,具体而言:首先,由进程申请一个空白PCB,并向PCB中填写用于控制和管理进程的信息;然后,为该进程分配运行时所必需的资源;最后,把该进程的状态转换为就绪状态并将其插入就绪队列之中。但如果进程所必需的资源尚不能得到满足,如系统尚无足够的内存来存储进程,此时创建工作尚未完成,进程不能被调度运行,于是我们把此时进程所处的状态称为创建状态(或新建状态)。
    引入创建状态,是为了保证进程的调度必须在创建工作完成后进行,以确保对PCB操作的完整性。同时,创建状态的引入也增加了管理的灵活性,OS可以根据系统性能或内存容量的限制,推迟新进程的提交(使进程处于创建状态)。对于处于创建状态的进程,当其获得了所必需的资源,并完成了对PCB的初始化工作后,便可由创建状态转入就绪状态。
  • (2)终止状态
    进程的终止也要通过两个步骤:首先,等待OS进行善后处理;然后,将进程的PCB清零,并将PCB空间返还OS。当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被OS所终止,或是被其他有终止权的进程所终止时,它就会进入终止状态。进入终止状态的进程不能再被执行,但在OS中依然会保留一个记录,其中会保存状态码和一些计时统计数据以供其他进程收集。一旦其他进程完成了对其信息的提取,系统就会删除该进程,即将其PCB清零,并将该空白PCB返还OS。图2-7所示为增加了创建状态和终止状态后,进程的5种状态及其转换关系。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

2.2.3 挂起操作和进程状态的转换

在许多系统中,为了满足系统和用户观察与分析进程的需要,除了就绪、执行和阻塞这3种最基本的状态外,还引入了一个面向进程的重要操作——挂起。当该操作作用于某个进程时,该进程将被挂起,这意味着此时该进程处于静止状态。例如,如果进程正在执行,则其此时会暂停执行;如果进程原本处于就绪状态,则其此时暂不接受调度。与挂起操作对应的操作是激活操作

1. 挂起操作的引入

引入挂起操作主要是为了满足下列需要。

  • (1)终端用户的需要。终端用户自己的程序在运行期间发现有可疑问题,希望暂停程序运行,以便用户研究其执行情况或对其进行修改。
  • (2)父进程的需要。有时父进程希望挂起自己的某个子进程,以便考查和修改该子进程,或者协调各子进程间的活动。
  • (3)负荷调节的需要。当实时系统中的工作负荷较重,可能会影响到对实时任务的控制时,系统可把一些不重要的进程挂起,以保证自身能正常运行。
  • (4)OS的需要。OS有时希望挂起某些进程,以便检查在进程运行过程中资源的使用情况或进行记账。所记录的信息包括CPU时间、实际使用时间、作业或进程数量等。

2. 引入挂起操作后进程 3 个基本状态间的转换

引入挂起原语Suspend激活原语Active(二者须成对使用)后,在二者的共同作用下,进程可能会发生以下几种状态转换。

  • (1)活动就绪→静止就绪。进程处于未被挂起的就绪状态,称为活动就绪状态,表示为Readya,此时进程可以接受调度。当用挂起原语Suspend将该进程挂起后,该进程的状态便转换成了静止就绪状态,表示为Readys。处于Readys状态的进程不会再被调度执行
  • (2)活动阻塞→静止阻塞。进程处于未被挂起的阻塞状态,称为活动阻塞状态,表示为Blockeda。当用挂起原语Suspend将该进程挂起后,进程的状态便转换成了静止阻塞状态,表示为Blockeds。处于该状态的进程在其所期待的事件发生后,它将从静止阻塞状态变为静止就绪状态。
  • (3)静止就绪→活动就绪。处于Readys状态的进程,若用激活原语Active将其激活,则该进程的状态将会转换为Readya状态。
  • (4)静止阻塞→活动阻塞。处于Blockeds状态的进程,若用激活原语Active将其激活,则该进程的状态将会转换为Blockeda状态。
    在这里插入图片描述

3. 引入挂起操作后进程 5 个基本状态间的转换

在这里插入图片描述引入创建和终止状态后,进程在进行状态转换时,与图2-8所示的进程5个状态转换相比较,要额外考虑下面的几种情况。

  • (1)NULL→创建:一个新进程产生时,该进程处于创建状态。
  • (2)创建→活动就绪:在当前系统的性能和内存容量均允许的情况下,当完成进程创建的必要操作后,相应地系统会将进程状态转换为活动就绪状态。
  • (3)创建→静止就绪:在当前的系统资源状况和性能要求不允许的情况下,系统不会分配给新建进程所需资源(主要是内存),相应地系统会将进程状态转换为静止就绪状态。进程被安置在外存,不参与调度,此时进程创建工作尚未完成。
  • (4)执行→终止:当一个进程已完成任务,或是出现了无法克服的错误,或是被OS或其他进程所终止时,将进程状态转换为终止状态。

2.2.4 进程管理中的数据结构

一方面,为了便于使用和管理计算机中的各类资源(包括硬件和信息),OS将它们抽象为相应的各种数据结构,并提供了一组对资源进行操作的命令;用户可利用这些数据结构及操作命令来执行相关的操作,而无须关心其实现的具体细节。另一方面,OS作为计算机资源的管理者,为了协调诸多用户对系统中共享资源的使用,它还必须记录和查询各种资源的使用情况及各类进程的运行情况等信息;OS对于这些信息的组织和维护,也是通过建立和维护各种数据结构的方式来实现的。

1. OS 中用于管理资源和控制进程的数据结构

在计算机系统中,对于每个资源和每个进程都设置了一个数据结构,用于表征其实体,我们称之为资源信息表和进程信息表,其中包含了资源和进程的标志、描述、状态等信息以及一批指针。通过这些指针,可以将同类资源和进程的信息表,或者同一进程所占用的资源信息表分类链接成不同的队列,以便OS进行查找。如图2-10所示,OS管理的这些控制表一般可分为以下4类:内存表、设备表、文件表和用于进程管理的进程表,通常进程表又被称为PCB。本小节着重介绍PCB,
在这里插入图片描述

2. PCB 的作用

  • 为了便于系统描述和管理进程,OS为每个进程专门定义了一个数据结构——PCB。PCB作为进程的一部分,记录了OS所需的、用于描述进程当前情况以及管理进程运行状态的全部信息,是OS中最重要的记录型数据结构,常驻内存。
  • PCB的作用是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,即一个能与其他进程并发执行的进程。
  • 下面将对PCB的具体作用做进一步的阐述。
    • (1)作为独立运行基本单位的标志。当一个程序(含数据)配置了PCB后,就表示它已是一个能在多道程序环境下独立运行的、合法的基本单位了,即具有了取得OS服务的权利,如打开文件系统中的文件,请求使用系统中的I/O设备,以及与其他相关进程进行通信等。因此,当系统创建一个新进程的同时,就会为它建立一个PCB。进程结束时系统又会回收其PCB,进程也随之消亡。系统是通过PCB来感知进程的存在的。事实上,PCB已成为进程存在于系统中的唯一标志
    • (2)实现间断性运行方式。在多道程序环境下,程序是采用“停停走走”这种间断性的方式运行的。当进程因阻塞而暂停运行时,它必须保留自己运行时的CPU现场信息,因为其再次被调度运行时,还需要恢复CPU现场信息。在有了PCB后,系统就可以将CPU现场信息保存在被中断进程的PCB中,供该进程再次被调度运行而须恢复CPU现场信息时使用。由此可再次明确,在多道程序环境下,作为传统意义上的静态程序,其因并不具有保护或保存自己运行现场的手段,故无法保证运行结果的可再现性,从而失去了运行的意义。
    • (3)提供进程管理所需要的信息。当调度程序调度到某进程时,只能根据该进程PCB中记录的程序和数据在内存或外存起始地址(又称为“始址”或“基址”)中找到相应的程序和数据;在进程运行过程中,当进程需要访问文件系统中的文件或I/O设备时,也都需要借助PCB中的信息。另外,还可根据PCB中的资源清单了解到该进程所需的全部资源等信息。由此可见,在进程的整个生命期中,OS总是根据PCB来实施对进程的控制和管理的
    • (4)提供进程调度所需要的信息。只有处于就绪状态的进程才能被调度运行,而在PCB中就提供了进程所处状态等信息。如果进程处于就绪状态,系统便会把它插入进程就绪队列中,等待调度程序的调度;另外,在进行进程调度时,往往还需要了解进程的其他信息,如在优先级调度算法中,就需要知道进程的优先级;在有些较为公平的调度算法中,还需要知道进程的等待时间和已执行时间等信息。
    • (5)实现与其他进程的同步与通信。进程同步机制是用于实现各进程的协调运行的,在采用信号量机制时,它要求在每个进程中都要设置相应的用于同步的信号量。在PCB中还具有用于实现进程通信的区域或通信队列指针等。

3. PCB 中的信息

在PCB中,主要包括下述4方面的信息。

  • (1)进程标识符
    进程标识符用于唯一地标志一个进程。一个进程通常有两种标识符。

    • ① 外部标识符。为了方便用户(进程)对进程的访问,须为每个进程设置一个外部标识符。它是由创建者提供的,通常由字母和数字组成。为了描述进程的家族关系,还应设置父进程标识符和子进程标识符。此外,还可设置用户标识符,以指示拥有该进程的用户。
    • ② 内部标识符。为了方便系统对进程的使用,在OS中又为进程设置了内部标识符,即赋予每个进程唯一的一个数字标识符,它通常是一个进程的序号。
  • (2)处理机状态
    处理机状态信息,也称为处理机的上下文,主要是由处理机的各种寄存器中的内容组成的。这些寄存器包括:

    • ①通用寄存器,又称为用户可视寄存器,它们可被用户程序访问,用于暂存信息,在大多数处理机中,有8~32个通用寄存器,在RISC中可超过100个;
    • ②指令计数器,其中存放了要访问的下一条指令的地址;
    • ③程序状态字寄存器,其中含有状态信息,如条件码、执行方式、中断屏蔽标志等;
    • ④用户栈指针寄存器,指每个用户进程都有一个或若干个与之相关的系统栈,用于存放进程和系统的调用参数及调用地址。栈指针指向该栈的栈顶。

    处理机处于执行状态时,正在处理的许多信息都是放在寄存器中的。当进程被切换时,处理机状态信息都必须保存在相应的PCB中,以便在该进程被重新调度时,能再从断点处继续执行。

  • (3)进程调度信息
    OS在进行进程调度时,必须了解进程的状态以及有关进程调度的信息,这些信息包括:

    • ①进程状态,指明进程的当前状态,作为进程调度和对换时的依据;
    • ②进程优先级,描述进程使用处理机的优先级别(用一个整数表示),优先级高的进程应优先获得处理机;
    • ③进程调度所需要的其他信息,如进程已等待CPU的时间总和、进程已执行时间总和等,它们与所采用的进程调度算法有关;
    • ④事件,指进程由执行状态转换为阻塞状态所等待发生的事件,即阻塞原因。
  • (4)进程控制信息
    进程控制信息是指用于进程控制所必需的信息,包括:

    • ①程序和数据的地址,即进程中程序和数据的内存或外存起始地址,便于再调度到该进程执行时,能从PCB中快速找到其程序和数据;
    • ②进程同步和通信机制,这是实现进程同步和进程通信时所必需的机制,如消息队列指针、信号量等,它们可能会全部或部分放在PCB中;
    • ③资源清单,在该清单中列出了进程在运行期间所需的全部资源(除CPU外);
    • ④链接指针,它给出了本进程所在队列中的下一个进程的PCB的始址。
      在这里插入图片描述

4. PCB 的组织方式

在一个系统中,通常可拥有数十个、数百个乃至数千个PCB。为了能对它们加以有效的管理,应该用适当的方式将这些PCB组织起来。目前常用的组织方式有以下3种。

  • (1)线性方式。将系统中所有的PCB都组织在一张线性表中,将该表的起始地址存放在内存的一个专用区域中。该方式实现简单且开销小,但每次查找时都需要扫描整张表,因此适合进程数目不多的系统。图2-11所示为PCB线性表示意。
  • (2)链接方式。通过PCB中的链接字,将具有相同状态的进程的PCB分别链接成一个队列。这样即可形成就绪队列、若干个阻塞队列和空闲队列等。对就绪队列而言,其往往会按进程的优先级将PCB从高到低进行排列,即将优先级高的进程的PCB排在队列的前面。同样,也可根据阻塞原因的不同,把处于阻塞状态的进程的PCB排成多个阻塞队列,如等待I/O操作完成的队列和等待分配内存的队列等。图2-12所示为PCB链接队列示意。
  • (3)索引方式。系统根据所有进程状态的不同,建立几张索引表,如就绪索引表、阻塞索引表等,并把各索引表在内存中的起始地址记录在内存的一些专用单元中。在每个索引表的表目中,记录具有相应状态的某个PCB在PCB表中的地址。图2-13所示为PCB索引方式示意。
    在这里插入图片描述
    在这里插入图片描述

2.3 进程控制

进程控制是进程管理中最基本的功能,其负责创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、转换运行中进程的状态(进程状态转换)等。例如,当一个正在运行的进程因等待某事件而暂时不能继续运行时,将其置于阻塞状态,而在该进程所期待的事件出现后,又将其置于就绪状态。进程控制一般是由OS内核中的原语来实现的。

2.3.1 进程的创建

1. 进程的层次结构

  • 在OS中,允许一个进程创建另一个进程,通常把创建进程的进程称为父进程(parentprocess),而把被创建的进程称为子进程(progeny process)。子进程可以继续创建其自己的子进程(即父进程的孙进程),由此便形成了进程的层次结构。如在UNIX系统中,进程与其子孙进程可以共同组成一个进程家族(进程组)
  • 了解进程间的这种关系是十分重要的,因为子进程可以继承父进程所拥有的资源,例如,继承父进程所打开的文件和分配到的缓冲区等。当子进程被撤销时,应将其从父进程那里获得的资源归还给父进程。此外,在撤销父进程时,也必须同时撤销其所有的子进程。为了标志进程间的家族关系,在PCB中设置了家族关系表项,以标明自己的父进程及所有的子进程。进程不能拒绝其子进程的继承权。
  • 值得注意的是,在Windows系统中不存在任何进程层次结构的概念,所有的进程都具有相同的地位。在一个进程创建了另外一个进程后,创建进程获得一个句柄,其作用相当于一个令牌,可以用来控制被创建的进程。但是这个句柄是可以进行传递的,也就是说,获得了句柄的进程拥有控制被创建进程的权力,因此,进程之间的关系不再是层次关系了,而是获得句柄与否、控制与被控制的简单关系。

2. 进程图

  • 为了形象地描述一个进程的家族关系,引入了进程图(process graph)。所谓进程图,就是用于描述进程间关系的一棵有向树,如图2-14所示。图中的节点代表进程。若进程B创建了进程D,则称B是D的父进程,D是B的子进程。
    在这里插入图片描述

  • 这里可用一条由进程B指向进程D的有向边来描述它们之间的父子关系。创建父进程的进程称为祖先进程,这样便形成了一棵进程树,树的根节点作为进程家族的祖先(ancestor)。

3.引起进程创建的事件

为使程序之间能并发执行,应先为它们分别创建进程。导致一个进程去创建另一个进程的典型事件有4类。

  • 用户登录:在分时系统中,用户在终端键入登录命令后,若登录成功,则系统将会为该用户创建一个进程,并把它插入就绪队列中。
  • 作业调度:在多道批处理系统中,当作业调度程序按一定的算法调度到某个(或某些)作业时,便会将它(们)装入内存、为它(们)创建进程,并把它(们)插入就绪队列中。
  • 提供服务:当运行中的用户程序提出某种请求后,系统将专门创建一个进程来为用户提供其所需要的服务,例如,用户进程要求打印文件,系统将为它创建一个打印进程,这样,不仅可使打印进程与该用户进程并发执行,还便于计算出完成打印任务所须花费的时间。
  • 应用请求:在上述3种情况下,都是由系统内核为用户创建一个新进程;而针对“应用请求”这类事件,则需要由用户进程自己创建新进程,以使新进程以同创建进程并发执行的方式完成特定任务。例如,某用户进程需要不断地先从键盘终端读入数据,再对读入的数据进行相应的处理,最后将处理结果以表格的形式显示在屏幕上。该用户进程为使这几个操作能并发执行以加速完成任务,可以分别建立键盘输入进程、数据处理进程以及表格输出进程。

4.进程的创建

在系统中每当出现创建新进程的请求时,OS便会调用进程创建原语,并按下述步骤创建一个新进程。

  • (1)申请空白PCB
    • 为新进程申请一个唯一的数字标识符,并从PCB集合中索取一个空白PCB。
  • (2)为新进程分配其运行所需的资源,包括各种物理和逻辑资源,如内存、文件、I/O设备和CPU时间等。
    • 这些资源从OS或其父进程获得。新进程对这些资源的需求详情,一般也要提前告知OS 或其父进程。例如,为新进程的程序和数据以及用户栈分配必要的内存空间时,OS必须知道新进程所需内存的大小:①对于批处理作业,其大小可在用户提出创建进程要求时提供;②对于为应用进程创建子进程,也应在该进程提出创建进程的请求中给出所需内存的大小;③对于交互型作业,用户可以不给出内存要求而由系统分配一定的内存空间,如果新进程要共享内存中的某个地址空间(即已装入内存的共享段),则必须建立相应的链接。
  • (3)初始化PCB
    • PCB的初始化工作包括:①初始化标志信息,将系统分配的标识符和父进程标识符填入新PCB中;②初始化处理机状态信息,使程序计数器指向程序的入口地址,使栈指针指向栈顶;③初始化处理机控制信息,将进程的状态设置为就绪状态或静止就绪状态,此外,通常还须将其设置为最低优先级,除非用户以显式方式提出高优先级要求。
  • (4)如果进程就绪队列能够接纳新进程,就将新进程插入就绪队列
    • 当进程创建新进程时,有两种执行的可能:
      父进程与子进程并发执行;
      父进程等待,直到其某个或全部子进程执行完毕。
    • 新进程的地址空间也有两种可能:
      子进程是父进程的复制品(即子进程具有与父进程相同的程序和数据);
      子进程加载另一个新程序。
  • 上述不同功能的实现,能以UNIX系统中创建新进程的系统调用fork()为例。使用fork()后创建的新进程是通过复制原进程的地址空间而形成的,这种机制支持父进程与子进程方便地进行通信。这两个进程(父进程和子进程)都会继续执行位于系统调用fork()之后的指令。
    • fork函数被调用后,‌它实际上返回两次,‌一次在父进程中,‌一次在子进程中,对于子进程,系统调用fork()的返回值为0;而对于父进程,返回值为子进程的进程标识符(非0)。
  • 通常,在系统调用fork()创建一个新进程(这个新的进程是当前进程的副本)后,新进程会使用另一个系统调用,即exec(),用新程序来取代进程的内存空间。系统调用exec()会将二进制文件装入内存(取代了原来包含系统调用exec()程序的内存映射),并开始执行。采用这种方式,两个进程能够相互通信,并能按各自的方法执行。父进程能创建更多的子进程,或者如果在子进程运行时父进程没有事情可做,那么它可以使用系统调用wait()把自己移出就绪队列以等待子进程的终止。

2.3.2 进程的终止

1.引起进程终止的事件

(1)正常结束,表示进程的任务已经完成,准备退出运行。在任何系统中,都应有一个用于表示进程已经运行完成的指示。在批处理系统中,通常会在程序的最后安排一条Holt指令,用于向OS表示运行已结束。当程序运行到Holt指令时,将产生一个中断以通知OS本进程已运行完毕;在分时系统中,用户可利用Logs off来表示进程运行完毕,此时同样可产生一个中断以通知OS本进程已运行完毕。
(2)异常结束,是指进程在运行时,发生了某种异常事件,使程序无法继续运行。常见的异常事件有:①越界错,程序所访问的存储区已越出该进程所占存储区域的范围;②保护错,进程试图去访问一个不允许访问的资源或文件,或者以不适当的方式进行访问,例如,进程试图去写一个只读文件;③指令错,程序试图去执行一条不存在的指令(非法指令),出现该错误的原因可能是程序错误地转移到了数据区,把数据当成了指令;④特权指令错,进程试图去执行一条只允许OS执行的指令;⑤运行超时,进程的运行时间超过了设定的最大值;⑥等待超时,进程等待某事件的时间超过了指定的最大值;⑦算术运算错,进程试图去执行一个被禁止的运算,例如,被0除;⑧I/O错,这是指在I/O过程中发生了错误等。
(3)外界干预,是指进程应外界的请求而终止运行。这些干预有:①操作员或OS干预,如果系统中发生了某事件,例如,发生了系统死锁,则由操作员或OS采取终止某些进程的方式,把系统从死锁状态中解救出来;②父进程请求,当子进程已完成父进程所要求的任务时,父进程可以提出请求以结束该子进程;③父进程终止,即当父进程终止时,它的所有子孙进程都应当结束,因此,OS在终止父进程的同时,也会将它的所有子孙进程终止。

2.进程的终止过程

当系统中发生了要求终止进程的某事件后,OS便会调用进程终止原语,按下述步骤终止指定的进程:①根据被终止进程的标识符,从PCB集合中检索出该进程的PCB,并从该进程的PCB中读出该进程的状态;②若被终止进程正处于执行状态,则立即终止该进程的执行,并置调度标志为真,以指示该进程被终止后应重新进行调度;③若该进程还有子孙进程,则还应终止其所有子孙进程,以防止它们成为不可控的进程;④将被终止的进程所拥有的全部资源,或归还给其父进程,或归还给系统;⑤将被终止进程的PCB从所在队列(或链表)中移出,等待其他程序来搜集信息。

2.3.3 进程的阻塞与唤醒

1.引起进程阻塞与唤醒的事件

有下述几类事件会引起进程阻塞或进程唤醒。

  • (1)向系统请求共享资源失败。进程在向系统请求共享资源时,由于系统已无足够的资源分配给它,此时进程会因不能继续运行而将自身状态转变为阻塞状态。例如,一个进程请求使用打印机,由于系统已将打印机分配给了其他进程,已无可再分配的打印机,这时,请求进程只能被阻塞,仅在其他进程释放出打印机后,请求进程才会被唤醒。
  • (2)等待某种操作的完成。当进程启动某种操作后,如果该进程必须在该操作完成之后才能继续执行,则应先将该进程阻塞起来,以等待该操作完成。例如,进程启动了某I/O设备,如果只有在I/O设备完成了指定I/O操作任务后进程才能继续执行,则该进程在启动了I/O设备后,便应自动进入阻塞状态去等待。在I/O操作完成后,再由中断处理程序将该进程唤醒。
  • (3)新数据尚未到达。对于相互合作的进程,如果一个进程需要先获得另一进程提供的数据后,才能对该数据进行处理,则只要其所需数据尚未到达,进程便会阻塞。例如,有两个进程,进程A用于输入数据,进程B用于对输入的数据进行加工。假如A尚未将数据输入完毕,则B将会因没有所需处理的数据而阻塞;A一旦把数据输入完毕,便可去唤醒B。
  • (4)等待新任务的到达。在某些(特别是在网络环境下的)OS中,往往会设置一些特定的系统进程,每当这种进程完成任务后,便会把自己阻塞起来,以等待新任务的到来。例如,在网络环境中的发送进程,其主要任务是发送数据包,若已有的数据包已全部发送完成,而又无新的数据包需要发送,这时发送进程就会把自己阻塞起来;仅当有新的数据包到达时,系统才会将发送进程唤醒。

2.进程阻塞过程

正在执行的进程,如果发生了上述某事件,进程便会通过调用阻塞原语block将自己阻塞。由此可见,阻塞是进程自身的一种主动行为。进入block阶段后,由于该进程还处于执行状态,因此系统应首先立即停止执行该进程,把PCB中的现行状态由执行改为阻塞,并将PCB插入阻塞队列。如果系统中设置了因不同事件而阻塞的多个阻塞队列,则应将该进程插入具有相同事件的阻塞队列。最后,转至调度程序进行重新调度操作,将处理机分配给另一就绪进程并进行切换,即保留被阻塞进程的处理机状态,并按新进程的PCB中的处理机状态设置CPU的环境

3.进程唤醒过程

当被阻塞进程所期待的事件发生时,例如它所启动的I/O操作已完成,或其所期待的数据已到达,有关进程(如提供数据的进程)就会调用唤醒原语wakeup以将等待该事件的进程唤醒。wakeup的执行过程是:首先把被阻塞的进程从等待该事件的阻塞队列中移出,将其PCB中的现行状态由阻塞改为就绪;然后再将该PCB插入就绪队列中。

应当指出,block原语和wakeup原语是一对作用刚好相反的原语。在使用它们时,必须成对使用,即如果在某进程中调用了阻塞原语,则必须在与之相合作的或其他相关进程中调用一条相应的唤醒原语,以便能唤醒被阻塞的进程;否则,阻塞进程将会因不能被唤醒而永久地处于阻塞状态,再无机会继续运行。
在这里插入图片描述

2.3.4 进程的挂起与激活

1.进程的挂起

当系统中出现引发进程挂起的事件时,OS就会利用挂起原语suspend将指定进程或处于阻塞状态的进程挂起。suspend的执行过程是:首先,检查被挂起进程的状态,若为活动就绪状态,则将其改为静止就绪状态;其次,针对处于活动阻塞状态的进程,将其状态改为静止阻塞状态;再次,为了方便用户或父进程考查该进程的运行情况,把该进程的PCB复制到某指定的内存区域;最后,若被挂起的进程正在执行,则转向调度程序重新调度

2.进程的激活

当系统中出现激活进程的事件时,OS就会利用激活原语active将指定进程激活。active的执行过程是:首先将进程从外存调入内存,然后检查该进程的现行状态,若是静止就绪,则将其改为活动就绪;若是静止阻塞,则将其改为活动阻塞。假如采用的是抢占调度策略,则每当有静止就绪进程被激活而插入就绪队列时,便应检查是否要进行重新调度,即由调度程序将被激活进程与当前进程两者的优先级进行比较,如果被激活进程的优先级较低,就不必重新调度;否则,立即终止当前进程的运行,并把处理机分配给刚被激活的进程

进程的切换

在这里插入图片描述

计算机操作系统-第二章 进程的描述与控制 下——进程通信和线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值