当前位置: 首页 > news >正文

操作系统学习笔记第2章 (竟成)

第 2 章 进程管理

【考纲内容】

1.进程与线程:
(1) 进程 / 线程的基本概念;
(2) 进程 / 线程的状态与转换;
(3) 线程的实现:内核支持的线程;线程库支持的线程;
(4) 进程与线程的组织与控制;
(5) 进程间通信:共享内存;消息传递;管道;信号

2.CPU 调度与上下文切换:
(1) 调度的基本概念;
(2) 调度的目标;
(3) 调度的实现:调度器 / 调度程序(scheduler);调度的时机与调度方式(抢占式 / 非抢占式);闲逛进程;内核级线程与用户级线程调度;
(4) CPU 调度算法;
(5) 多处理机调度;
(6) 上下文及其切换机制

3.同步与互斥:
(1) 同步与互斥的基本概念;
(2) 同步与互斥的基本方法:软件实现方法;硬件实现方法;
(3) 锁;
(4) 信号量;
(5) 条件变量;
(6) 经典同步问题:生产者 - 消费者问题;读者 - 写者问题;哲学家进餐问题

4.死锁:
(1) 死锁的概念;
(2) 死锁预防;
(3) 死锁避免;
(4) 死锁检测和解除

【考情统计】

年份

单选题数

综合题数

总分值

考点

2009

1

1

9

典型调度算法、死锁原因、P/V 操作

2010

4

0

8

进程控制、典型调度算法、信号量机制、饥饿问题

2011

4

1

16

典型调度算法、线程概念和多线程模型、银行家算法、同步机制、P/V 操作

2012

4

0

8

进程概念与特征、线程概念和多线程模型、调度基本概念、进程概念、线程概念、线程实现、线程组织、银行家算法

2013

2

1

11

典型调度算法、银行家算法、P/V 操作

2014

4

1

16

进程状态与转移、典型调度算法、进程通信、死锁、P/V 操作

2015

2

1

13

进程状态与转换、进程控制、死锁避免、死锁检测、P/V 操作

2016

5

1

16

调度的基本概念、典型调度算法、死锁原因、硬件同步、互斥机制、管程机制、饥饿问题

2017

2

1

12

调度的方式、典型调度算法、调度算法、P/V 操作

2018

6

0

12

进程的状态与转移、调度的方式、典型调度算法、状态转换、互斥机制、银行家算法、管程机制、同步机制

2019

4

1

16

线程概念和多线程模型、典型调度算法、死锁原因、银行家算法、死锁预防、死锁解除、P/V 操作

2020

4

1

15

进程概念与特征、调度算法的目标、典型调度算法、银行家算法、互斥机制、临界资源、P/V 操作

2021

4

1

15

进程状态、进程组织、典型调度算法、调度的方式、调度时机、互斥机制、临界资源

2022

3

1

14

进程组织、典型调度算法、银行家算法、进程状态

2023

2

2

13

进程状态、典型调度算法、硬件同步

2024

3

1

14

进程终止、进程切换、线程、P/V 操作综合题

【考点解读】

        本章是选择题和综合题考查的重点章节。进程与线程一节中,历年考查的形式为概念相关的选择题。一般考查 1 道选择题,与其他章节内容结合考查时可能命制 2 道选择题。处理器调度与上下文切换一节中,着重考查调度相关的概念选择题和典型调度算法相关的计算选择题,一般考查 1 道选择题。2016 年的 408 试卷比较特殊,针对调度的概念考查了一次综合题,请考生注意。
        进程同步是十分重要的一节,408 统考几乎每年都会考查 1 道 7 分左右的综合应用题,此外还会以客观题的形式考查临界资源与临界区、同步与互斥等基本概念。如果考生充分掌握信号量机制的应用,得分并不困难。死锁一节中,平均每年考查 1 道选择题,其中对银行家算法的考查尤为侧重,值得考生重点关注。另外,进程间信号通信机制、多处理机调度是 2025 考研 408 大纲中新增考点。

【复习建议】

关于本章考生应:

1.理解进程的概念与特征、线程的概念、多线程模型。

2.重点掌握进程的状态转移,进程的控制相关内容。

3.了解进程的组织,其中 PCB 相关内容需要理解。

4.理解线程和进程之间的相同点和不同点。

5.了解进程通信的四种方式,尤其注意管道、共享内存和消息传递机制。

6.了解调度的机制、时机、方式和实现,这有助于考生对调度有一个全面的了解。

7.重点掌握调度算法的目标。

8.重点掌握典型调度算法。本章列举的七种调度算法中,除了多级队列(注意不是多级反馈队列)以外,都应该熟练掌握。

9.甘特图是分析调度的工具,建议熟练运用于涉及调度的计算中。

10.理解进程同步、临界区、临界资源的基本概念。

11.重点掌握同步机制的四个设计准则,它们为后续知识作了重要铺垫。

12.了解实现临界区互斥的基本方法,重点关注其中的 Peterson 算法。

13.重点掌握信号量的类型及其应用,可以应用信号量实现进程的同步、互斥和前驱关系。

14.重点掌握生产者 - 消费者问题、哲学家进餐问题、读者 - 写者问题等经典同步问题,力求熟练使用 P/V 操作解决复杂的多进程同步问题。

15.了解管程的定义、组成和基本特性。

16.理解死锁的定义和原因,重点掌握死锁产生的四个必要条件。

17.了解资源问题和资源分配图。

18.理解死锁预防、死锁检测和解除的概念和方法。

19.重点掌握死锁避免的概念和方法,重点关注其中的安全状态和银行家算法。

2.1 进程与线程

        本节的目标是对进程的概念、组织、控制、通信问题以及线程的概念、线程实现方式有一个全面的认识。进程和线程是操作系统的基本概念,也是考试重点考查的内容。尽管本节考查的知识范围广,但难度适中,对于进程和线程的理解到位后,很多知识点记忆负担不大。考生在学习本节内容时,可以先尝试对进程和线程建立起一个总体的认识,通过本节的各个例子和提示加深理解,尝试回答下列问题(答案见本章末总结)。
        (1) 什么是进程,有什么特点?是否可以举出一个实际的例子?
        (2) 一个进程由哪些部分组成,为什么要提出进程这一概念?
        当考生可以回答上述问题时,说明已经对本节知识点有了一定的理解,接下来需要针对各个知识点进行系统性学习,当能回答以下问题时,说明已经系统地掌握了本节(题目可以在各个小节中找到答案)。
        (1) 进程在其生命周期中,有哪些状态?这些状态间哪些状态是可以转移的,什么场合下可以转移?
        (2) 进程控制有哪些原语?以进程创建为例,能否说出进程创建原语发生在哪些场合,具体执行过程是什么?
        (3) PCB 中有哪些内容,为什么需要这些内容?
        (4) 进程通信有哪些方式?

2.1.1 进程的概念和特征

1. 进程的概念

        自诞生以来,操作系统就需要运行各种各样的程序。为了管理这些程序的运行,操作系统提出了进程(Process)这一概念。进程(Process)是计算机中一个执行的程序实例,每个进程对应一个运行中的程序。是操作系统资源分配和调度的独立单位,是操作系统中最基础与最重要的概念之一。有了进程这一概念,应用程序在运行时仿佛独占了 CPU,而不用考虑何时需要将 CPU 让给其他程序;进程的管理等任务则交给操作系统。
        一个进程包括了以下内容:程序段(Program Code)、数据段和进程控制块。其中,程序段和数据段是一组指令、数据和对其组织描述的总和;操作系统通过进程控制块(参见本节进程控制块)描述程序的 “状态”。
        程序段与数据段存储在磁盘上,是静态的;进程是指将这些程序与数据从磁盘加载到内存后的执行过程,是动态的,多个进程可以对应于同一段程序代码。
        【举例】“int a = 1;” 包含了指令与数据,而我们写程序时有序地将代码组织起来,就是在对其组织进行描述。Windows 操作系统中一个 exe 文件就是一个程序,执行该程序就会创建一个对应进程,执行多次该文件会创建出多个对应进程,所以进程是动态的,是一次执行过程。
这里列举更多角度下对进程的定义:
        (1) 进程是程序的一次执行过程 。
        (2) 进程是一个程序及其数据在处理器上顺序执行时所发生的活动 。
        (3) 进程是具有独立功能的程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的独立单位 。
        (4) 进程是正在计算机上执行的程序实例 。
        (5) 进程是能分配给处理器并由处理器执行的实体 。
        (6) 进程是由一组执行的指令、一个当前状态和一组相关的系统资源表征的活动单元 。
        (7) 进程由程序段、数据段、进程控制块三部分组成。
        【举例】在现实世界中,我们准备好了各种的食材(数据)并编写了一个料理配方(每个步骤的操作 + 将操作合理地组织),这就对应了一个程序。按照料理配方开始料理食材的过程,就对应了一个进程。显然,我们可以使用一个料理配方对两批食材同时处理,这就相当于开启了两个进程;在料理一批食材的过程中,安排多个人同时进行料理,这就相当于开启了多个线程。

2. 进程控制块

        进程控制块(Process Control Block,PCB),是操作系统为每个进程配备的一个记录型数据结构。PCB 上包含了操作系统管理进程所需要的信息,用于管理操作系统中存在的所有进程,是进程的组成部分之一。进程与线程的组织一节会详细介绍 PCB 的主要内容、功能。
        【提示】考生第一次接触到 PCB 这个概念时,可以类比学生档案。一个班级(对应操作系统)会有一份记录所有学生信息的表格(对应 PCB),每个学生有一个独一无二的学号(对应进程标识符)以及其他重要信息,如是否报到(对应进程状态)等。操作系统用 PCB 来记录和管理所有进程,就像班级管理者利用学生档案来记录和管理每一位学生。

3. 进程的特点

        与程序相比,进程主要有以下 4 个特点。理解进程的并发性、独立性和异步性时,可以和批处理系统中作业的顺序执行进行对比学习。

(1) 动态性

        进程的实质是程序在多道系统中的一次执行(Execution),从创建到消亡,是动态的、具有生命周期的。与此相对,程序只是一串二进制位,静态存储于硬盘等介质之中,并不具有动态性。

(2) 并发性

        引入进程概念后,操作系统中可以有多个进程并发执行。当多个进程并发执行时,会有以下 3 个特性:

(a) 间断性

        并发的进程会有间断运行的特点。当多个进程协同完成同一任务时,需要进行同步等操作,进而导致进程的暂停。例如,两个进程 Pa​、Pb​ 协作处理一组数据。Pa​ 需要对 Pb​ 处理后的数据进行进一步处理,那么 Pa​ 在得到 Pb​ 数据前,会陷入阻塞态。Pa​ 进程的执行过程可以描述为:执行 —— 阻塞 —— 就绪 —— 执行。

(b) 失去封闭性

        当系统中存在多个进程并发执行时,这些并发进程将会共享系统中的各类资源。任意进程都可能改变某个资源的状态,从而影响到其他进程。失去封闭性意味着进程的执行结果与执行速度有关,使得进程的执行有不可再现性。失去封闭性导致了不可再现性。

(c) 不可再现性

        并发执行的进程,在相同的初始环境和条件下,可能得到不同的结果。这是因为进程失去了封闭性。例如,进程 Pa​ 和 Pb​ 共享一个整数型共享变量 M,Pb​ 的工作是对 M 进行三次加一操作,Pa​ 的工作是读出 M 的值,则 Pb​ 进程运行的快慢会直接导致 Pa​ 读出的结果不同。
        【提示】重温并发(Concurrent)和并行(Parallel)两个概念。并发是多个进程在同一时间段内运行,在同一时刻仅有一个进程处于执行态;并行则是同一时刻多个进程处于执行态。在单处理器多道程序系统中,进程可以并发执行;在多处理器系统中,进程不但可以并发执行,还能并行执行。

(3) 独立性

        进程是操作系统调度和资源分配的最小单位,即一个进程能够独立运行。各个进程获得的资源独立于其他进程。

(4) 异步性

        因为异步性,进程的执行、暂停等变得不可预知,进程以不可预知的状态向前推进。
        【提示】进程的并发性导致了进程的异步性。通过使用多种同步手段(参见本章同步与互斥),可以保证在异步性的前提下得到确定(可再现)的结果。

2.1.2 进程的状态与转移

1. 进程的五种状态

        由于进程的并发特征,进程在操作系统中呈现出间断运行的规律,因此进程在其生命周期中会经历不同的状态。408 考试大纲中要求掌握进程的五种状态:创建状态、就绪状态、执行状态、阻塞状态、终止状态,如图 2.1 所示。其中,就绪状态、执行状态、阻塞状态三个状态称为基本状态,因为在一个进程的生命周期中,这三种基本状态可以多次切换,而创建状态和终止状态在整个周期中只能有一次。所以在讨论进程的状态转移问题时,常常用三状态模型一词对其描述。简洁起见,后文使用创建态、就绪态、执行态、阻塞态、终止态指代上述五种状态。

(1) 创建(New)态

        当进程第一次被创建时所处的状态。在此状态下,进程等待着由此状态转换为 “就绪态”。操作系统决定进程由创建态转换为就绪态时,一般会考虑系统资源的占用情况。若当前系统资源紧张,系统会推迟处于创建态的进程转换为就绪态。

(2) 就绪(Ready)态

        当一个进程获得了其他所有资源,等待处理器的分配时,其状态为就绪态。在此状态下,进程排队等待系统为其分配处理器资源。就绪态是很常见的状态,处理器作为 “珍贵” 的资源,很难同时分配给所有就绪态的进程。
        【提示】尽管计算机可以有多个处理器,但是依然难以满足所有进程对处理器资源的请求。在一个单处理器的计算机中,任意时刻最多只能有一个进程处于执行态,其他进程只能处于其他状态。由于处于就绪态的进程很多,这些进程一般被放在就绪队列中等待调度。后续的处理器调度章节中,会详细讨论将处理器分配给进程的各种调度算法。

(3) 执行(Running)态

        当一个进程被分配处理器并开始执行时,就进入了执行态。进程中的程序代码得以在处理器上运行。
        【提示】内核态下,进程能同时访问内核和用户地址、不受限制地访问硬件,执行特权指令;用户态下,进程不能访问内核的指令和数据。这种模式的设计保证了安全性。

(4) 阻塞(Block)态

        阻塞态是指进程在执行过程中因为发生某些事件而导致无法继续执行的状态。将进程转换为阻塞态是因为:操作系统不希望进程因为等待未到来的数据或条件而导致处理器的空闲,系统效率下降。
        【提示】导致进程进入阻塞态的事件很多,可能是进程发生了 I/O 操作,等待关键数据从磁盘读入内存;可能是进程申请访问临界资源但该临界资源被其他进程占有(详见本章进程同步一节)。

(5) 终止(Terminated)态

        当进程结束时,就会进入终止态。进入终止态的原因可能是进程正常地结束,也可能是被用户强制结束(例如 Linux 中向进程发送 KILL 信号,或 Windows 下在任务管理器中结束进程)。该状态下,操作系统开始回收该进程占有的资源。
        【拓展】① 终止态中有一个术语:僵尸进程(Zombie Process)。用来描述那些已经处于终止态但却未被从系统进程表中删除的进程。Unix 系统中,有父进程的子进程可能会发生这种情况。僵尸进程会占用进程号,对系统的危害是:可能导致系统中没有可用的进程号而无法产生新进程。② 父进程已经结束运行,但它的子进程还在运行,将这些子进程称为孤儿进程。孤儿进程会被进程号为 1 的 init 进程所收养,并由 init 进程完成其状态收集等善后工作。孤儿进程对系统没有危害。
进程的五种状态特点对比如表 2.1 所示。

2. 进程的状态转换

进程可能出现的状态转换及对应的原因如表 2.2 所示。表 2.2 中进程状态转换说明如下:
(1) 创建态→就绪态:进程创建成功后,首先会被设置为就绪态,插入就绪队列中。
(2) 就绪态→执行态:处于就绪态的进程被调度后,转换为执行态并分配处理器,运行。
(3) 执行态→就绪态:处于执行态的进程在其运行过程中,由于分配给它的处理器时间片用完而让出处处理器,变为就绪态。
        【提示】还有很多情况会导致这种状态转换。在抢占式操作系统中,当有优先级更高的进程变为就绪态时,当前正在使用处理器的进程会让出处处理器并由执行态变为就绪态。
(4) 执行态→阻塞态:当处于执行态进程请求某资源且必须等待时,会(主动)转换为阻塞态。
(5) 阻塞态→就绪态:当处于阻塞态的进程得到之前请求的全部资源后,会被唤醒(被动)并转换为就绪态。
(6) 执行态→终止态:当处于执行态的进程运行完毕、发生错误、被用户或操作系统强制终止时,会转换为终止态。
        【提示】阻塞态无法直接转换为执行态,这取决于调度算法的设计。调度算法调度的对象就是就绪队列中的进程,故一个进程结束阻塞态后,会先转换为就绪态。

2.1.3 进程组织

        进程是操作系统资源分配的最小单位,在未引入线程概念的操作系统中,同样是调度的最小单位。一个进程包含了代码段、数据段以及进程控制块 PCB。

1. 进程控制块 PCB

① PCB 的功能概述

PCB 主要有以下五个功能。
        (1) 作为独立运行基本单位的标志:当一个程序(含数据)配置了 PCB 后,就表示该程序能够在支持多道程序的系统上独立运行。
        (2) 实现进程的间断运行:在多道程序环境下,进程的运行是断断续续的。当一个进程由执行态转换为其他状态时,必须要保留该进程运行时的处理器现场信息,用于之后的处理器现场恢复。如果没有 PCB 来保存进程停止运行时的现场信息,那么该进程便失去了间断运行的能力。
        (3) 提供进程管理的重要信息:例如,当调度程序希望某个进程运行时,会通过 PCB 中的对应指针,找到该进程存储在内 / 外存上的程序和数据。PCB 中还会记录进程打开文件、拥有资源等多种信息,用以实现进程管理的多种功能。
        (4) 提供进程调度所需要的信息:PCB 上存储了进程的状态,用于帮助调度程序合理地完成调度。有些调度算法还需获知进程的等待时间等信息,这些信息往往也存储于 PCB 中。
        (5) 实现与其他进程的同步与通信:操作系统为实现进程间的同步与通信,在 PCB 中也设置了相应的数据结构。例如,采用信号量机制实现进程同步时,信号量就是位于 PCB 中。

② PCB 中的内容

不同的操作系统内核对于 PCB 这一数据结构的实现不尽相同,PCB 中内容如表 2.3 所示,总体分为四类:
        (1) 标识符:标识符是唯一标识,以数字或数字加字母的形式存储在 PCB 中。Linux 中,每个进程都有一个称为 PID(Process ID)的进程标识符。


        (2) 处理器状态信息:处理器状态信息又称为处理器上下文,记录进程在执行态下关键寄存器的信息,用于进程切换后恢复处理器上的重要信息。涉及的寄存器主要有:①通用寄存器;②程序计数器 (Program Counter, PC);③程序状态字 (Program State Word, PSW);④用户栈指针。
        【提示】PCB 中存储的寄存器数量和种类都不是固定的,取决于处理器的设计。PCB 存储的寄存器信息用于上下文切换,故 PCB 也被称为切换帧 (Switch Frame),就好像在进程停止运行前对处理器上的各种重要信息做了一个 “快照”,当操作系统想要重新让暂停的进程继续运行时,只需要把之前保存的信息恢复到处理器即可。
        (3) 处理器调度信息:该类信息的存储取决于操作系统使用何种调度方法来将处理器分配给进程,该类信息一般包括:
(a) 进程调度状态:记录执行态、就绪态、阻塞态等。
(b) 进程调度优先级:在多个进程就绪时,用于决定哪个进程先获得处理器资源。
(c) 调度的相关信息:这取决于调度算法。例如进程已使用的处理器时间、进程等待处理器的时间等,这些信息用于实现操作系统的调度算法。
(d) 事件:指进程由执行态转换为阻塞态的原因。记录进程的阻塞原因,可以帮助操作系统更好地设计各个进程的优先级。
        (4) 进程控制信息:用于进程控制所必须的信息,包括:
(a) 代码段和数据段的地址:在 PCB 中通过指针的方式标明其在内存或外存中的位置。
(b) 进程同步和通信机制:用来实现进程同步的信号量、消息队列指针等。
(c) 资源清单:记录操作系统分配给该进程的全部资源,用于资源分配和回收等。
(d) 链接指针:PCB 所在队列中下一个进程的 PCB 首地址。操作系统为了能对 PCB 加以有效管理,一般按照进程所处的状态将各 PCB 存储于不同的队列(如就绪队列、若干阻塞队列)中,这些队列往往以链表的方式实现,这也是 PCB 中存储下一个 PCB 首地址的原因。

2.1.4 进程控制

        本小节我们讨论操作系统如何管理进程,包括创建和结束进程、转换进程等。计算机在进程的控制方面,往往使用原语 (Primitive) 完成。原语,也有教材称作原子操作 (Atomic Operation),是指由若干条指令组成用于完成某个行为的过程。原语是不可中断的,即一个原语中的指令要么全部被执行,要么全部不执行。在进程同步一章中,还会学习 P/V 原语。原语保证了使用者能够得到确定的结果。
        【提示】请考生思考两个问题。第一,为什么需要把多个指令设计成一个原语,例如 GetAndSet 指令能不能由 get 指令加上 set 指令代替?假设一个设备一次只能由一个进程使用,操作系统使用 flag 变量标记是否有进程使用该设备,0 代表空闲,1 代表忙碌。一个进程使用该设备需要进行两步操作:①获得 flag 值,如果 flag==0 则进行下一步,否则等待;②将 flag 值置为 1 并使用该设备。此时 PA​,PB​ 均想要使用该设备,如果上述两个步骤不是原语操作,则可能发生这样的执行序列:PA​ 成功执行①;PB​ 成功执行①;PA​ 成功执行②并开始使用设备;PB​ 成功执行②并开始使用设备。这样就发生了错误,因为两个进程都认为自己可以使用设备。如果上述两个步骤是原语操作,就不会出现这种错误。
        第二,为什么在进程控制的过程中要使用原语?因为进程创建、进程唤醒等一系列控制操作均包含了多个步骤,要确保这些步骤全部进行或全部不进行才能得到正确的结果。假设需要进行进程唤醒操作,该操作至少分为两个步骤:①将待唤醒进程的状态设置为就绪态;②将该进程放入就绪队列中。倘若①和②不是原语操作,在执行完①后,发生中断,则此时一个就绪态的进程却被放在了阻塞队列中,这样就发生了错误。

1. 进程的创建

① 进程创建的场合

进程创建的场合主要有以下四类:
(1) 用户登录时。
(2) 高级调度发生时:即作业由外存等待队列被调度到内存中,进行初始化的场合。
(3) 系统响应用户程序提出的请求时:此时操作系统会创建对应的服务进程。情况 1、2、3 均是操作系统内核为用户创建进程。
(4) 现有进程创建新进程时:用户进程可以通过创建新进程来提高程序并发度。例如用户希望同时从键盘接受输入、处理数据、将数据转为统计图显示在屏幕上,就可以在数据处理进程之外新建键盘输入进程和统计图展示进程。

② 进程创建原语的执行过程

(1) 为在创建中的新进程分配一个进程标识符(PID),作为进程的唯一标识;为进程分配空白 PCB,用于记录进程的各类资源与信息。
(2) 为该新进程分配所需资源。包括各类的物理资源和逻辑资源,如内存、文件、I/O 设备和处理器时间等。
(3) 初始化 PCB 上的内容。包括进程标识符、父进程标识符、处理器状态信息和处理器控制信息。
(4) 若上述过程顺利,将该新进程状态设置为就绪态,放入就绪队列,等待调度;若不顺利,分配资源不足时,则创建该新进程的父进程置为阻塞态,新进程仍处于创建状态。
【提示】各种操作系统在进程创建原语的设计上不尽相同,以 Linux 为例,除了 PID 为 0 的进程以外,其余的进程都是由 PID 为 0 的进程创建而来的,而这个 “0” 进程是内核进程,相比于其他进程的数据结构都是动态分配的,它的数据结构是静态的。Linux 提供了 fork、vfork 和 clone 三种函数用于进程创建,这里简单了解即可。

2. 进程的终止

进程是一个动态的执行过程,这意味着一个进程必然会迎来它的结束。

① 进程终止的场合

(1) 进程运行完毕,正常退出。
【举例】Linux 系统中的 exit 系统调用,就是用于向操作系统汇报当前进程的工作已经完成,可以终止并回收资源。C 语言中,main 函数执行 return 0 后也会运行完毕,正常退出。
(2) 进程运行中发生出现无法恢复的异常(如整数除以零、访问越界等)而退出。
(3) 被其他进程或操作系统杀死。
【举例】Linux 系统中,得知其他进程的 PID 后,就可以使用 kill 系统调用可以向这一进程发送信号来强制结束对应的进程。

② 终止原语的执行过程

(1) 根据进程的进程号(PID),找到进程对应的 PCB,获取进程的状态。
(2) 修改该进程的状态,置为终止态。
(3) 若该进程运行期间调用了进程创建指令,创建了子进程, 则要把其子进程也进行终止。
(4) 将分配给该进程的所有资源收回:①如果该进程有父进程,则将资源归还给其父进程,这个进程会成为僵尸进程,其 PCB 会被保留;②如果没有父进程,则将资源归还给操作系统。
(5) 将被终止进程的 PCB 从所在队列中移除;若该进程原先处于执行态,则应再从就绪队列中调度一个进程执行。

3. 进程的阻塞和唤醒

        当进程请求资源失败(资源不足、资源未到达等)或等待某个事件发生时,该进程无法继续执行,便会执行阻塞原语,让出处理器资源,变为阻塞态。当进程请求的资源到达或等待的事件发生时,相关进程可调用唤醒原语,通知之前因等待而变为阻塞态的进程,使其变为就绪态。
        【提示】进程阻塞的过程是主动的,由进程自己调用阻塞原语来自 我阻塞(因此进程只能从运行态转为阻塞态,不能由就绪态转为阻塞态);而进程唤醒的过程是被动的,由其他进程调用唤醒原语来唤醒自己。此外,正常情况下,阻塞原语和唤醒原语一定是成对出现的,这样才能保证进程不会被无限期阻塞。

① 进程阻塞发生在以下几个场合

(1) 进程向系统请求临界资源(详见进程同步一节)失败。
        【举例】考虑一台计算机拥有 3 台打印机资源且均已经被分配给其他进程,此刻进程 PA​ 请求使用 1 台打印机,则 PA​ 会调用阻塞原语。等其他进程释放了打印机资源,才会唤醒 PA​ 继续执行。
(2) 进程等待某种操作的完成:进程在执行过程中,一些操作有着严格的先后顺序。
        【举例】在进程启动了 I/O 设备希望读取数据后,该进程必须等待 I/O 设备将数据读取完毕,才能进行之后的操作。这个等待期间,进程会触发阻塞原语进入阻塞态,等待 I/O 操作完成后,再由中断处理程序将进程唤醒。
(3) 新数据尚未到达。
        【举例】考虑进程 PA​、PB​ 相互协作的情况,如果 PA​ 需要 PB​ 的相关数据才能继续运行,则 PA​ 在等待数据时会进入阻塞态,直到 PB​ 向 PA​ 提供数据并将其唤醒。
(4) 等待新任务的到达:当前进程无任务需要处理,但等待着下一个任务的到来,就可以在等待的过程中将自己阻塞。
        【举例】例如网络操作系统中的某些系统进程,在完成任务后,会自我阻塞并等待新任务到来。

② 阻塞原语的执行过程

(1) 根据进程的 PID,找到进程对应的 PCB,获取进程的状态。
(2) 若该进程此时为执行态,则将其置为阻塞态,将其 PCB 插入到阻塞队列中。
(3) 进行上下文切换,从就绪队列中选择一个进程,将其转换为运行态并为其分配处理器,使其可以运行。

③ 进程唤醒发生在以下几个场合:
(1) 进程向系统请求临界资源失败后,使用该临界资源的进程释放了该资源。
(2) 进程等待的操作已经发生。
(3) 进程等待的数据到达。
(4) 进程获得了一个新的任务。
【提示】进程唤醒发生的场合与阻塞发生的场合相对应,记住阻塞发生的场合,自然能想到进程唤醒发生的场合。
④ 唤醒原语的执行过程:
(1) 找到阻塞队列中对应进程的 PCB。
(2) 更改该进程状态为就绪态,将该进程的 PCB 放入就绪队列中。

4. 进程切换

        进程切换,指操作系统内核挂起当前运行的进程,调度就绪进程占用处理器运行。进程切换的过程中,通过 PCB 保存处理器状态信息。
        【提示】因为进程切换需操作系统内核的支持,所以进程切换必然发生在内核态而非用户态。
        为什么需要进程切换?操作系统对计算机的各类资源进行管理,而这些资源又是有限的。为了满足每个进程使用资源的请求,操作系统需要进行处理器调度,即决定哪些资源在哪些时间里归哪些进程使用,而进程切换,就是实现处理器调度的手段之一。
① 上下文切换(Context Switch)
        上下文切换,指保存和恢复处理器上的信息,狭义上,可以认为是保存当前使用处理器进程的相关信息,并将待调度进程的处理器信息恢复到处理器上。“上下文” 一词,可以理解为进程的工作环境。考虑进程 PA​ 要进行进程切换,必须把当前时刻处理器上的重要信息(如寄存器信息)记录,就好像是一张快照。无论之后的其他进程怎样设置处理器上的数据,在 PA​ 重新占有处理器时,操作系统把之前的上下文恢复,从 PA​ 的角度而言,就好像没有任何进程使用过处理器一样。
        【提示】因考纲中使用 “上下文切换” 这一说法,故下文统一使用该种说法。
        【举例】有两个进程 PA​、PB​。PA​ 正在占用处理器运行,处理器中的寄存器里存有它的数据,比如 PC 寄存器存储了该进程执行的代码地址、CR3 寄存器存储了该进程的页表基地址。此时操作系统决定暂停 PA​,让进程 PB​ 使用处理器,之后有机会再让 PA​ 继续运行。那么,当 PA​ 再一次使用处理器时,如何保证处理器中寄存器的内容不变呢?倘若不在 PA​ 放弃处理器时保留该瞬间的一些信息,其他进程使用处理器时就会把这些信息搞得一团糟。可以想象,当 PA​ 重新占有处理器时,曾经处理器中的信息已经改变,那么这个进程就不能继续正常运行了。
② 上下文切换的时机
        上下文切换发生在操作系统从执行态进程处获得控制权的任意时刻。中断、陷阱、系统调用,这些事件都会导致控制权移交给操作系统。上下文切换是进程调度的实现手段之一,是进程调度的一个环节,需结合进程调度的相关内容进一步理解。在 2.2.2 调度的时机这一小节,会讨论调度可以发生的场合和不可以发生的场合,这些场合同样适用于分析上下文切换。
③ 上下文切换过程:
(1) 保存处理器的上下文,例如上文提到的一些重要寄存器。这些信息存储在进程对应的 PCB 中。
(2) 修改进程状态,并将该进程的 PCB 放入对应的队列。
(3) 调度程序选择另一个进程执行。
(4) 读取待调度进程的 PCB,修改其运行状态为执行态。
(5) 更新内存管理的数据结构。
【提示】这一步涉及地址转换知识,请学习内存管理一章后再做了解。
(6) 恢复待调度程序的上下文环境。
(7) 根据程序计数器 (PC) 指向的位置找到下一行执行的代码,恢复该进程。
④ 模式切换:
        模式切换指处理器在不同模式间转换的过程,如果当前操作系统拥有内核态和用户态两个状态,那么模式切换即指从内核态转换为用户态或用户态转换为内核态的过程。
模式切换发生在中断处理的过程中。当处理器检查中断信号并发现存在未处理的中断时,需要执行对应的中断处理程序。具体过程为:将 PC 置为中断处理程序的起始地址,从用户态转换为内核态来获得执行特权指令的权限。这一过程中,需要将①中断处理可能改变的信息;②恢复程序运行需要用到的信息保存到被中断程序的 PCB 中。
        【提示】上下文切换不是模式切换。模式切换确实涉及上下文环境的保存,但和进程切换是不相同的,模式切换可以不改变正处于执行态进程的状态,这种情况下,保存和恢复上下文环境的开销更小。

2.1.5 线程概念和多线程模型

1. 线程的定义

        线程(Threads),是比进程更小的概念,也称轻量级进程(Light Weight Process, LWP),是将进程进一步细分的单位。在多道程序操作系统中,引入了进程的概念,用于解决单处理器环境中程序的并发执行问题。为了进一步提高程序的并发执行程度,又引入了线程的概念,一个进程可以同时拥有多个线程,借助多个线程实现程序的并发执行(而不必借助进程),事实也证明线程的引入确实能改善操作系统的性能,所以多数现代操作系统都引入并实现了线程这一概念。
        【提示】后文会提到用户级线程和内核级线程,一般教材中提到的轻量级进程特指通过内核实现的线程,注意区分。
        未引入线程概念时,进程有两个特点:是资源所有权和调度 / 执行的单位。前者指一个进程拥有对资源的控制和所有权,包括内存、I/O 通道、I/O 设备等;后者指进程是一个可以被操作系统调度的独立实体。线程可以理解为在调度 / 执行这一属性上对进程进一步细分。
        【提示】在引入线程前,进程是操作系统调度的最小单位;在引入线程且是由操作系统内核支持的线程后,线程是操作系统调度的最小单位。同时,进程仍然是操作系统分配资源的最小单位,线程的引入并未改变进程资源所有权这一特点。

2. 引入线程的优势

(1) 进一步提高并发性

        线程可以进一步细化进程中的各种任务,提高任务的并发性。在单处理机系统中,线程模型可以分离同一个进程内的 CPU 计算和 I/O 访问,让它们并发进行。在多处理机系统中,引入线程模型前,无论有多少处理机,一个进程都只能占用一个处理机;引入线程模型后,每个线程都能占用一个处理机,这使得多处理机系统的优势得以充分发挥。
        【提示】线程和进程在很多概念和设计理念上,是极其相似的。例如进程的提出,就是想让多个作业能够同时在操作系统中运行,防止一些作业阻塞时浪费处理器资源的情况,而线程则是让一个作业的多种活动进一步细分,例如一个作业需要请求外存数据以及进行大量的计算,在请求资源且未得到回复时,另一个线程仍然可以进行计算,无需因为等待结果的返回而阻塞。

(2) 共享地址空间与可用数据

        进程间由于相互的 “隔离”,无法直接共享数据,这就带来了进程间通信的问题。而线程模型的引入,使得并行实体拥有了共享地址空间、数据的能力,换言之,线程之间可以直接共享数据而不需要经由操作系统内核,在速度上有很大优势。

(3) 线程更轻量级

        线程无论是创建、切换还是撤销,都远快于进程。在很多操作系统中,一个线程的创建较进程的创建快 10 - 100 倍。在短时间需要反复开启或撤销大量线程时,线程的轻量级是十分有优势的。

(4) 提高交互性

        线程还能提高图形界面程序的交互性,避免程序 “卡死”。例如,一个运行中的文字编辑器就可以是一个由多线程构成的进程。假设这个进程只有两个功能:接收用户的输入以及将当前的文件存储到外存。若该进程未引入线程概念,当用户命令其存储文件时,进程就会进行 I/O 请求直到 I/O 响应,在此期间对于用户的任何操作,编辑器均不会做出响应。如果该进程引入线程概念并开启两个线程(分别对应文件存储工作和与用户交互工作),那么在一个线程请求并等待响应时,另一个线程还能接受用户请求,从而使用户得到更好的体验。

3. 线程的组织

        一个操作系统中的多个进程之间具有很大的独立性,而进程中的多个线程则不同,它们拥有完全相同的地址空间,这意味着它们可以共享全局数据。一个多线程的进程模型如图 2.2 所示。每个线程访问的地址空间,都由其所在进程拥有。同一进程的不同线程间甚至可以修改对方的堆栈上的数据,这种情况下,多个线程间是没有保护的。但是,“没有保护” 不是线程的缺点,而是使得线程间能够共享数据的优点。同一个进程的多个线程是属于同一用户的,该用户创建多个线程的目的是让其彼此更好地配合完成作业,因此用户在编程时就会避免多个线程之间可能出现的互相干扰行为,使这些线程间不会因为 “没有保护” 而相互干扰。

(1) 线程的三个基本状态

        和传统的进程相似,线程也有三个基本状态:执行态、阻塞态、就绪态。线程状态之间的转换和进程状态之间的转换是一样的,可参考图 2.1。
(a) 执行态:在该状态下,线程获得处理器并运行。
(b) 就绪态:表示线程可以被调度执行,被分配处理器就可以立刻执行工作。
(c) 阻塞态:指线程在执行过程中,因为某些事件而阻塞并等待。
【举例】线程申请了 I/O 操作并等待结果的返回,则它进入阻塞态。

(2) 线程控制块 TCB

        和进程类似的,每个线程也具有一个对应的线程控制块(Thread Control Block, TCB),用于控制和管理线程的状态、保存线程的信息。线程控制块中通常有以下几类信息:
(a) 线程标识符(TID):每个线程的唯一标识符。
(b) 寄存器信息:用来记录包括通用寄存器、程序计数器、状态寄存器等关键寄存器的信息。
(c) 线程执行状态:用于记录线程的执行状态。
(d) 优先级:用于线程调度。
(e) 线程专有存储区:用于线程切换时保存现场信息。
(f) 信号屏蔽:每个线程拥有各自的信号屏蔽字。
(g) 堆栈指针:TCB 中分别设置了两个指向堆栈的指针,分别指向用户自己的堆栈和核心栈。每个线程都有自己的堆栈,在线程运行过程中,会进行过程调用(或称函数调用),就可以把过程调用相关的局部变量以及调用完成之后的返回地址存储在堆栈中。
        【提示】核心栈是线程运行在内核态时使用的。
        【举例】有三个过程(函数) FA​、FB​、FC​:FA​ 调用了 FB​,FB​ 调用了 FC​,在 FC​ 执行时,FA​、FB​、FC​ 三个过程的变量和返回地址都会存储在堆栈上。

4. 线程的实现

        如图 2.3 所示,根据操作系统的不同,线程的实现方式也不完全相同,主要分为两类:内核级线程(Kernel Supported Threads, KST)和用户级线程(User - Level Threads, ULT)。


【提示】不同文献对线程实现方式的英文称呼不尽相同,有的文献还会使用 Kernel - Level Thread 来表示内核级线程。

(1) 用户级线程

        线程的管理由应用程序实现,在用户空间下完成。操作系统内核感知不到线程的存在,在该种方式下,调度的最小单位依然是进程,线程的调度则由其所在进程实现。

(2) 内核级线程

        线程和进程一样,均需要操作系统内核的支持,其创建、阻塞、撤销和切换都是在内核空间下实现的,内核通过 TCB 来对线程进行感知和控制。在该种方式下,线程是调度的最小单位。

5. 用户级线程

① 用户级线程的优点

(1) 可以在不支持线程的操作系统中实现线程。具体实现上,主要通过用户空间的线程库实现,应用程序使用线程库进行多线程设计,进程通过调用函数开启多线程。
(2) 可以允许进程自主定制调度算法。操作系统只负责把处理器与其他资源分配给进程,由进程继续将这些资源分配给该进程创建的线程,线程的调度与资源分配都由进程自主完成,可以更好地安排各个线程的工作,也使得线程具有更好的扩展性。
(3) 线程的切换完全在本进程中完成而没有内核的参与,所以这种实现方式的效率更高。
【提示】所有线程相关的数据结构都在进程的用户地址空间,所以线程的切换不需要转换成内核态,这就避免了两次状态转换带来的开销。

② 用户级线程的缺点

(1) 一旦某个线程被阻塞,该线程所属的整个进程都会被阻塞。
(2) 如果只使用用户级线程,一个多线程程序不能利用多处理器技术。因为操作系统只会为一个进程分配一个处理器,所以一个进程中只能有一个线程处于执行态。
【提示】对于这两个缺点,也有对应的解决方法,例如将多线程程序转换为多进程程序、使用 jacketing 技术克服阻塞等,此处了解即可。

6. 内核级线程

① 内核级线程的优点

(1) 在多处理系统中,内核可以调度一个进程内的多个线程到多个处理器上运行。
(2) 当一个线程被阻塞,内核可以调度该进程中的另一个线程到处理器上运行。
(3) 操作系统内核自身可以使用多线程。

② 内核级线程的缺点

(1) 线程切换时,需要内核介入。模式切换带来了额外开销。
【提示】《操作系统精髓与设计原理》中提到,在 Null Fork 和 Signal - Wait 两个测试中,用户级线程的性能优于内核级线程,内核级线程的性能优于进程,且两两之间都有一个数量级以上的性能差距。

7. 用户级线程和内核级线程的组合方式

        有些操作系统把内核级线程和用户级线程两种方式组合,比如使用内核级线程,然后将用户级线程与内核级线程进行多路复用。采用这种方法时,编程人员可以决定有多少个内核级线程与多少个用户级线程对应。内核只识别内核级线程并对其进行调度,而这些内核级线程会被多个用户级线程多路复用。用户级线程和内核级线程之间有以下三种关系,考生可以结合图 2.3 中的 (c) 理解:

① 一对一模型

        一个用户级线程映射到一个内核级线程,相比于多对一模型,具有更好的并发,当一个线程被阻塞时,其余线程能够继续执行。缺点是太多的内核级线程会增加开销,影响程序性能。

② 多对一模型

        将多个用户级线程映射到一个内核级线程。这一模型的优点在于效率较高,线程切换在用户态就能完成;缺点在于如果一个用户级线程发生了阻塞,整个进程都将被阻塞;此外,由于同一进程的多个用户级线程共同映射到一个内核级线程上,这导致用户级线程无法在多处理机系统上并行运行。
【提示】在一对一模型的实现下,同一进程的不同线程间切换时,需要涉及内核状态转换;在多对一模型实现下,同一进程的不同线程间切换时,不需要涉及内核状态转换。

③ 多对多模型

        多对多模型。将 x 个用户级线程映射到 y 个内核级线程,其中 x > y。这种模型可以认为是上述两类模型的折中,避免了上述两个模型的缺点:编程人员可以创建任意多个用户级线程,这些线程也能在多核系统上并发运行。
【提示】若 x = y,则该模型退化为一对一模型;若 x < y,则该模型退化为一对一模型且有若干内核级线程的浪费。

2.1.6 进程和线程的对比

进程和线程有着很多类似的特征,传统进程相当于一个单线程进程,进程和线程的对比如表 2.4 所示。

表 2.4  线程和进程的对比

对比项

进程

线程

调度

不再是调度的最小单位(引入内核线程后)

是调度的最小单位

拥有资源

进程都是资源分配的基本单位

线程只拥有少量资源

并发性

多个进程间可以并发执行

一个进程的多个线程也能并发执行

独立性

只共享全局变量

只有少数资源不能共享,例如线程的栈区

系统开销

通信、进程切换开销大

通信、切换开销小

多处理机

单个进程只能运行在一个处理机上

多线程进程可以充分利用多处理机

其他

进程间相互不影响

用户级线程的阻塞会影响整个进程

        (1) 调度的最小单位:在未实现线程的传统操作系统中,进程是处理器调度的最小单位;在实现了线程的操作系统中,线程是处理器调度的最小单位。
        【提示】上述线程特指内核级线程,用户级线程并不是处理器调度的最小单位。详见上文线程的实现。
        (2) 并发性:在未实现线程的传统操作系统中,只有进程之间可以并发执行;在实现了线程的操作系统中,一个进程中的所有线程和不同进程中的不同线程均可以并发执行,从而提高了操作系统的并发性、资源利用率和系统吞吐量。
        【举例】未引入线程概念时,一个音乐播放进程只能播放音乐;引入线程后,该进程可以开启多个线程,分别实现音乐播放、显示歌词等任务,实现多个任务的并发执行。
        (3) 拥有资源:进程可以拥有资源且是资源分配的最小单位。线程的资源依赖于创建它的进程,每个线程除了一些最核心的资源是私有的,包括线程控制块 TCB、少量寄存器(程序计数器)和栈区外,剩下的资源全部依赖于进程,并与该进程的其他线程共享。
        (4) 独立性:线程间的独立性要比进程间的独立性低得多,多个线程可以共享进程的内存地址空间和资源;进程之间除了共享全局变量外,每个进程都拥有独立的地址空间和不同资源。
        【提示】进程的高独立性是为了防止进程与进程间的有意或无意的破坏,而一个进程的多个线程因为同属于一个所有者,不会相互破坏。降低独立性有利于提高线程间的通讯效率以及进一步提高并发性,同一进程的线程间可以便捷地实现通信,而进程间通信往往需要操作系统内核的支持。
        (5) 系统开销:线程的创建、撤销以及切换的代价远小于进程。此外,因为线程的独立性低,线程间的同步、通信的实现代价也小于进程。
        【举例】Solaris2 OS 中,线程的创建比进程的创建快 30 倍,切换比进程快 5 倍。

2.1.7 进程通信

        进程与进程在运行过程中需要相互协作和交换信息,例如:父进程安排子进程处理一批数据并将结果返回给自己。这就涉及一个重要的问题:如何进行通信?进程通信问题,称为 IPC(Inter Process Communication)问题。
实现进程通信需要解决三个问题:
(1) 进程通过何种方式把信息传递给其他进程。
(2) 保证多个进程在关键活动上不会重叠。
【举例】多个进程同时请求修改同一块共享内存,但是这块内存需要互斥访问,此时就发生了重叠,需要操作系统考虑并解决谁先访问、谁后访问、如何保证互斥的问题。
(3) 进程按照正确的顺序推进。
【举例】父进程安排子进程处理数据,得到子进程返回的数据后才能进行下一步计算,如何控制父进程和子进程按照用户希望的顺序执行?这也是操作系统需考虑和解决的问题。
        为什么会有上述的问题?进程之间是平等且互相隔离的,进程难以察觉到其他进程的存在,也难以察觉到自己被操作系统调度。当进程的状态转换为执行态以外的状态时,该进程的整个 “世界” 就停止了。所以在一个进程的视角中,自己独占了整个计算机的资源,从开始到结束一直在运行。只有这台计算机上的操作系统如 “上帝” 一样,能够看清楚无数个进程在以什么样的模式被组织与调度。

1. 进程通信机制综述

        通信机制可以进一步细分为低级通信方式与高级通信方式。①低级通信方式:通信效率低;通信对用户不透明,编程人员在使用时需要考虑更多方面的问题(数据的传输、进程间的互斥、同步等)。②高级通信方式:可以高效地实现大规模数据的传输;由操作系统以系统调用形式提供,实现细节、通信过程等问题对编程人员透明,从而减少编程负担。这里主要介绍进程通信的 5 种方法:信号量机制、共享存储机制、消息传递机制、管道通信机制和信号机制。这些进程通信机制的总结如表 2.5 所示。
【提示】本部分内容为宏观上的总结,考生可以在学习完本章进程同步一节后再回顾一遍。

(1) 信号量(Semaphore)机制

        信号量机制,可以有效地解决进程同步和互斥问题,进程通过执行 P/V 操作控制信号量,属于低级通信方式。
        【举例】实际使用时,编程人员会将信号量和实际资源联系在一起。若有 3 个打印机资源,就设置一个值为 3 的信号量。占用打印机时,进程执行 P 操作,使得信号量值减 1;释放打印机资源时,进程执行 V 操作,使得信号量加 1。

(2) 共享存储(Shared Memory)机制

        根据共享公用数据结构还是存储区,可以将该机制细分为以下两种方式。
        (a) 共享数据结构的通信方式:该种实现下,进程间共享同一个数据结构,编程人员需要考虑进程间的同步互斥问题,传输效率低,属于低级通信方式。
        (b) 共享存储区的通信方式:该种实现下,操作系统在内存中开辟一块共享存储区,多个进程可以对该内存区域进行读写,传输效率高,属于高级通信方式。当进程希望对共享存储区进行存取时,会将自己的虚地址空间映射到共享存储区,并向操作系统提出申请。
        【举例】某个网站同时只能有一个用户登录,该网站有一个留言板功能,不同的用户之间想交流时就轮流登录在留言板上写下自己的话。留言板就类似于上文提到的共享存储区。

(3) 消息传递(Message Passing)机制

        上文提到,虽然进程间相互独立难以感知,但是操作系统是可以有效管理所有进程的。进程间可以调用由操作系统实现的通信命令来传递消息。实现消息传递即分别实现 Send 和 Receive 两个原语,用于消息的发送和接收。消息传递系统是高级通信方式,可以细分为以下两类:
        (a) 直接通信方式:发送进程直接将消息发送给接收进程,将信息挂载到接收进程的消息队列上,接收进程从自己的消息队列中获取消息。
        (b) 间接通信方式:操作系统额外创建一片空间用于存储各种消息,类似一个信箱,发送进程和接收进程依靠这个中间实体实现信息的发送和接收。这种方式也被称为信箱通信模式,在计算机网络中被广泛运用。在信箱通信方式下,通过不阻塞发送,阻塞接收的方式实现进程的同步。
        【提示】就同一个信息的复制次数而言,间接通信方式需要两次复制:第一次是将信息从发送者进程的存储区复制至操作系统内核开辟的存储区,第二次是将信息从操作系统内核开辟的存储区复制到接收者进程的存储区;直接通信方式只需一次复制,即操作系统内核直接将消息从发送者进程的存储区复制到接收者进程的存储区;共享存储区通信方式则可以实现 0 复制,亦即发送者可以直接在共享存储区生成信息,生成后无需任何操作就能被接收者读取。
        回忆第一章所述,微内核操作系统将一部分操作系统的功能实现为用户态进程,换言之,很多系统调用都需要交给另一个进程来执行,它们的实现方式就是进程通信。因此,进程通信的效率很大程度上决定了微内核操作系统的效率。最早的微内核操作系统采用间接通信方式,每个系统调用都需要两次复制,因此效率较低;后来的微内核操作系统引入了直接通信方式,将两次复制减为一次,大大提高了运行效率。

(4) 管道(Pipeline)通信机制

        该方式下,使用一种共享文件来实现进程间通信。这种共享文件称为管道(或 pipe 文件),可连接一个读进程和一个写进程。写进程以字符流的形式,将数据送入管道,读进程通过管道将数据读出。操作系统实现管道机制需要提供三种机制:同步机制、互斥机制,和通信进程间确定对方存在的机制。管道具有以下特点:
(a) 同步:读进程和写进程需要相互配合,写进程向管道中写入一定量数据后,会进入阻塞状态,等待读进程将数据读出后将其唤醒;读进程在将管道中数据读完后,也会进入阻塞状态,等待写进程对管道写操作完毕后将其唤醒。
(b) 互斥:当有一个进程在对一个管道读 / 写时,其他想要读 / 写该管道的进程必须等待 。
(c) 管道需要通信双方确定对方的存在,否则会陷入阻塞。考生可以使用 Linux 的 FIFO 管道进行简单实验,创建一个 FIFO 文件并向管道中写入随机内容,在未出现读进程前,写入进程是处于阻塞状态的。
(d) 管道是一个固定大小的缓冲区(如 4KB),在内核中实现,其大小不受磁盘大小影响。
(e) 管道的实质是一个共享文件,读进程将管道视为输出文件,写进程将管道视为输入文件,管道通信可以利用文件系统机制实现。
(f) 读数据操作是一次性的,管道中的数据一旦被读取就会被抛弃。
(g) 管道是半双工通信的,某一时刻,数据只能单向传输,若希望实现双向传输(即全双工),可以使用两个管道,如图 2.4 所示。另外,管道以字符流进行读出和写入,子进程会继承父进程的管道并利用管道与父进程通信。

(5) 信号(Signal)通信机制(2025 考研 408 大纲新增内容)

        信号是一种具有单向事件通知能力的软中断,在 Linux 系统中有非常广泛的使用 。操作系统通过发送指定信号来通知进程某个事件发生,以迫使进程执行信号处理程序。信号处理完毕后,被中断进程将恢复执行 。
信号可以由用户、操作系统内核和进程产生:
① 用户:用户能通过输入特定字符来请求内核产生信号。例如:在 Unix、Linux 和其他类 Unix 操作系统中,用户按下中断键(通常是 Ctrl + C),操作系统会给前台进程组中的所有进程发送中断信号 SIGINT。
② 操作系统内核:当进程运行遇到错误时,操作系统内核检测到错误事件会发送信号给出错进程。例如:当数组下标越界时,操作系统内核会发送段错误 SIGSEGV 信号给进程。
③ 进程:进程之间可以通过系统调用产生信号进行通信。
【提示】在 Linux 系统中总共有 62 个信号:①编号为 1 ~ 31 的信号称为标准信号,这些信号在 Unix 和类 Unix 操作系统中是标准化的,每个信号都有其特定的用途;②编号为 34 ~ 64 的信号称为实时信号,这些信号是 Linux 独有的,用于应用程序之间自定义的进程间通信。

        在 Linux 系统中,32 号和 33 号信号被系统保留,没有赋予标准的名称和用途。
操作系统内核一般会通过如下 3 种方式之一来处理信号:
① 直接忽略:进程可以将信号处理函数设置为 SIG_IGN 来通知内核忽略大部分信号,但信号 SIGKILL 和信号 SIGSTOP 除外,不可忽略。
② 执行内核默认处理函数:对于未注册信号处理函数的信号,进程会执行其默认操作(大多为终止进程或直接忽略信号)。
③ 执行信号处理函数:进程可以通过系统调用(signal 或 sigaction)为特定信号注册处理函数,内核接收到信号时会将信号编号作为参数调用该函数。信号处理函数可以执行任何合法的操作,例如:清理资源、保存状态、通知其他进程等。
【提示】进程间信号通信机制是通过用户注册的信号处理函数来实现的。
常见的信号、信号值及功能如表 2.6 所示:

表 2.6 常见的信号、信号值及功能

信号名称

信号值

信号功能

SIGINT

2

中断信号,通常由用户按下 Ctrl + C 组合键产生,用于中断前台进程的执行

SIGILL

4

用于报告进程执行了 “非法指令”(例如:非法操作码、非法操作数、特权指令等)

SIGKILL

9

强制终止信号,无法被捕获、忽略或阻塞,用于立即终止进程

SIGCHLD

17

在子进程状态(终止、暂停、恢复执行)发生改变时通知父进程

SIGSTOP

19

停止信号,无法被捕获或忽略,用于暂停一个进程的执行

2.1.8 习题精编

1.下列关于进程叙述,错误的说法是( )。
A. 进程是动态的,而程序是静态的
B. 在内存中的程序段就是进程
C. 在进程的生命周期中,存在多种状态
D. 进程可以占有处理机运行,而程序不行

1.【参考答案】 B
【解析】 进程由程序段、数据段、进程控制块 PCB 三部分组成。B 选项认为程序段就是进程,这种观点片面且错误,进程运行需将程序段装入内存,但内存中的程序段并非进程。A 选项强调进程的动态性,C 选项强调进程的状态,D 选项表明进程是处理器调度单位,这些说法均正确。

2.进程在处理器上执行时,错误的说法是( )。
A. 进程是一个动态的过程,终有结束的时刻
B. 多个进程可以并发地在处理机上执行
C. 并行的进程之间都存在着相互依赖和制约的关系
D. 进程的并发执行可能导致程序的结果与进程执行速度有关

2.【参考答案】 C
【解析】 并行的进程之间,可利用信号量等机制实现同步、互斥等关系,但并非所有并行(或并发)进程间都存在相互依赖或制约关系。例如,系统中音乐播放进程和聊天进程运行时可毫无联系。A、B、D 选项是对进程特点的正确叙述。

3.下列关于并发进程特性的陈述,正确的是( )。
A. 进程是一个动态过程,其生命周期是连续的
B. 并发进程执行完毕后,一定能够得到相同的结果
C. 并发进程对共享变量的操作结果与执行速度无关
D. 并发进程的结果具有不可再现性

3.【参考答案】 D
【解析】 A 选项前半句正确,后半句错误,失去封闭性会使并发进程的执行结果与执行速度相关,这也导致并发进程具有不可再现性,所以 B、C 选项错误,D 正确。

4.进程的基本特征不包括( )。
A. 动态性
B. 并发性
C. 共享性
D. 异步性

4.【参考答案】 C
【解析】 进程的基本特征为动态性、并发性、独立性和异步性,C 选项共享性错误,进程间的隔离程度较高。

5.有若干并发进程均将一个共享变量 count 中的值减 1 一次,那么有关 count 中的值说法正确的是( )。
I. 肯定有不正确的结果
II. 肯定有正确的结果
III. 若控制这些并发进程互斥执行 count 减 1 的操作,count 中的值正确
A. I、III
B. II、III
C. III
D. 上述说法都不正确

5.【参考答案】 C
【解析】 只有当每个进程互斥修改 count 时,才能得到确定且正确的结果,所以 III 正确;若不控制进程互斥修改 count,结果是未知的(可能正确也可能错误),I、II 错误,因此选项 C 正确。

6.关于子进程和父进程的说法,下面正确的是( )。
A. 一个父进程可以创建若干个子进程,一个子进程可以从属于若干父进程
B. 父进程被撤销时,其所有的子进程也应该被相应撤销
C. 子进程被撤销时,其所属的父进程也被撤销
D. 一个进程必定有父进程或子进程

6.【参考答案】 B
【解析】 一个父进程可创建若干子进程,一个子进程只从属于一个父进程,A 错误。当父进程被撤销时,操作系统会收回分配给该进程的所有资源,并终止其创建的子进程,B 正确。子进程被撤销时,其父进程不会被撤销,C 错误。在 Unix 系统中,除进程 0 外,并非任意一个进程都一定有父进程或子进程,D 错误。

7.并发进程失去了封闭性是指( )。
A. 多个相对独立的进程以各自的速度推进
B. 并发进程的执行结果与速度无关
C. 并发进程执行时,在同时刻发生的错误
D. 并发进程共享变量,其执行结果与速度有关

7.【参考答案】 D
【解析】 进程的封闭性指进程执行结果只取决于自身,不受外界因素影响,即执行结果确定。当进程失去封闭性后,其执行结果会受速度影响,选项 D 正确。

8.下面的叙述中,错误的是( )。
A. 就绪态、执行态和阻塞态,是进程的三个基本状态
B. 因为并发进程的间断性,进程在其生命周期中,呈现出多种状态
C. 每个进程的创建态、终止态只能有一次
D. 进程申请处理器却未得到满足时,其状态应该是阻塞态

8.【参考答案】 D
【解析】 进程申请处理器资源时,表明该进程已获得除处理器外的全部资源,此时应处于就绪态而非阻塞态,D 选项错误。阻塞态下,进程需等待 I/O 数据返回或所等待事件发生,才会转换为就绪态参与处理器竞争。

9.进程的哪一种状态,是进程的基本状态且可以从另外两个基本状态转换而来( )。
A. 执行态
B. 就绪态
C. 阻塞态
D. 终止态

9.【参考答案】 B
【解析】 进程的三个基本状态是就绪态、阻塞态和执行态,其中就绪态可由阻塞态和执行态转换而来,就绪态不能转换为阻塞态,阻塞态也不能转换为执行态,所以正确答案是 B 选项。

10.在支持多道程序设计的操作系统中,调度程序会调度各个进程并发使用处理器,下列事件中,不一定能引起进程调度的是( )。
A. 处于执行态的进程进行 I/O 操作并等待结果返回
B. 一个新进程被创建并转换为就绪态
C. 处于执行态的进程发生错误
D. 处于执行态的进程时间片耗尽

10.【参考答案】 B
【解析】 当进程被创建并放入就绪队列时,不一定会引起调度,所以选 B。A、C、D 三种情况,均是执行中的进程因某些事件放弃处理器,此时操作系统必须调度下一个进程使用处理器。

11.下列事件中,会引起进程由执行态转换为就绪态的是( )。
A. 时间片耗尽
B. 进程等待某一事件的完成
C. 进程进行 I/O 请求并等待结果
D. 进程运行结束

11.【参考答案】 A
【解析】 B、C 使进程转换为阻塞态,D 使进程变为终止态,时间片耗尽使进程由执行态转换为就绪态,A 正确。

12.下列事件中,会引起进程由执行态转换为就绪态的是( )。
A. 一个新进程被创建并进入就绪队列
B. 进程发生错误
C. 被高优先级进程抢占处理器
D. 进程等待的事件发生

12.【参考答案】 C
【解析】 A 选项(创建新进程)不一定会导致当前运行进程的处理器被抢占,所以 A 选项错误,C 选项正确。进程发生错误会导致进程终止,B 选项错误;进程等待的事件发生时,会从阻塞态转换为就绪态,D 选项错误。

13.下列事件中,不会引起进程转换为阻塞态的是( )。
A. 进程等待某个事件的发生
B. 进程等待 I/O 请求的数据
C. 进程等待处理器使用权
D. 拥有前后驱关系的两个进程,后继进程等待前驱进程的信号

13.【参考答案】 C
【解析】 进程等待处理器使用权时处于就绪状态;等待其他事件和资源时处于阻塞状态。A、B、D 选项均涉及 “等待” 处理器以外的事件或资源,会使进程进入阻塞状态;C 选项进程等待处理器时处于就绪态,不会转换为阻塞态,故选 C。

14.关于进程的状态和状态转换,以下哪一种说法是正确的( )。
A. 进程由创建而产生,由调度而执行,因得不到资源而挂起,以及由撤销而消亡
B. 在具有挂起状态的进程管理中,处于挂起就绪状态的进程会因为申请资源失败而进入挂起阻塞状态
C. 进程在运行期间,不断地从一个状态转换到另一个状态,它可以多次处于就绪状态和执行状态,也可多次处于阻塞状态,但可能排在不同的阻塞队列
D. 正在执行的进程,若时间片用完,会进入阻塞状态

14.【参考答案】 C
【解析】 进程因得不到资源会进入阻塞态而非挂起态,挂起是指操作系统将进程从内存移到辅存,发生在中级调度过程中,A 错误。就绪挂起状态无法转换到阻塞挂起状态,B 错误。时间片用完后,进程通常转换为就绪状态,D 错误。

15.在进程状态切换时,引起内存与辅存之间交换数据的是( )。
A. 运行到就绪
B. 运行到等待
C. 运行到挂起
D. 就绪到运行

15.【参考答案】 C
【解析】 进程的三个基本状态间的转换都发生在内存中,所以 A、B、D 选项均不符合。挂起状态是将内存中的进程移动到辅存中,C 正确。建议考生先学习进程调度的三个层次相关内容,再做此题。

16.进程控制块是进程的重要组成部分,下列内容中,PCB 中不应该包括( )。
A. 进程标识符(PID)
B. 处理器状态信息
C. 进程状态
D. 互斥信号量

16.【参考答案】 D
【解析】 互斥信号量由操作系统管理,并不记录在 PCB 中,所以本题选 D。

17.进程控制块 PCB 中不可能包含的信息是( )。
A. 进程优先级
B. 进程状态
C. 进程执行的代码
D. 进程名

17.【参考答案】 C
【解析】 进程执行的代码属于代码段,和 PCB 一样是进程的组成部分,但不会包含在 PCB 中,所以本题选 C;A、B、D 选项内容均可出现在 PCB 中。

18.进程创建原语中,不需要包含的步骤是( )。
A. 分配空白 PCB
B. 分配处理器资源
C. 初始化 PCB 上内容
D. 分配内存资源

18.【参考答案】 B
【解析】 进程从创建到转换为就绪态的过程中,不包括分配处理器这一步骤,分配处理器资源发生在调度过程中,所以 B 选项错误。

19.下列选项中,导致创建新进程的操作是( )。
I. 用户登陆
II. 高级调度发生时
III. 操作系统响应用户提出的请求
IV. 用户打开了一个浏览器程序
A. 仅 I、IV
B. 仅 II 和 IV
C. 仅 I、II 和 IV
D. 全部

19.【参考答案】 D
【解析】 进程创建的场景可归为四类:用户登录时、高级调度发生时、系统响应用户请求时以及现有进程创建新进程时。I、II、III 显然正确,IV 中用户打开一个浏览器程序,通常也会创建一个或多个进程,所以答案选 D。

20.进程创建过程必需的内容是( )。
I. 建立进程控制块
II. 为进程分配 CPU
III. 为进程分配内存
IV. 将进程链入就绪队列
A. 仅 I、III
B. 仅 I
C. I、II、III
D. I、III、IV

20.【参考答案】 A
【解析】 II 不是进程创建必需的,分配处理器的行为发生在调度过程中(就绪态转换为执行态的过程)。IV 也不是进程创建必需的,在多数操作系统中,新进程创建后,若系统资源充足且就绪队列未满,通常会被链入就绪队列等待 CPU 调度;若资源不足或就绪队列已满,新进程可能会处于挂起态或阻塞态,直至资源可用或就绪队列有空位。I、III 是进程创建必需的。

21.下列关于用户进程被创建后的陈述,错误的是( )。
A. 一定会先进入就绪队列
B. 进程在其生命周期中,可能不会经历阻塞态
C. 当时间片耗尽后,进程转换为终止态
D. 操作系统会回收处于终止态进程的资源

21.【参考答案】 C
【解析】 一般情况下,时间片耗尽时,进程大多会转换为就绪态,只有当时间片耗尽且进程恰好运行结束时,才可能转换为终止态,C 错误。

22.一个进程在运行中,释放了一台磁带机资源和一台打印机资源,这个行为可能会导致( )。
A. 某进程由就绪态转换为执行态
B. 自身状态由执行态转换为就绪态
C. 某进程由阻塞态转换为就绪态
D. 系统中所有等待打印机资源的进程被唤醒

22.【参考答案】 C
【解析】 进程释放资源,可能会唤醒之前因请求该资源而阻塞的进程,使其由阻塞态转换为就绪态,A 错误,C 正确。释放打印机和磁带资源与释放处理器并转换为就绪态并无关联,B 错误。因为只释放了一台打印机资源,最多唤醒一个等待该资源的进程,D 错误。

23.进程被唤醒时一定会发生( )。
A. 该进程立即占用处理器运行
B. 进程的 PCB 移动到就绪队列之首
C. 优先级改变
D. 进程变为就绪态

23.【参考答案】 D
【解析】 进程被唤醒时,状态会转换为就绪态,且其 PCB 会进入就绪队列,D 正确。A 发生在就绪态转换为执行态的过程中。B、C 不是必然发生的,取决于操作系统的具体实现。

24.下列关于线程的叙述中,正确的是( )。
A. 一个进程只有一个线程
B. 线程之间的通信需要依靠操作系统内核实现
C. 线程只拥有少量私有资源,所以不能独立被调度
D. 属于不同进程的线程,它们的地址空间相互独立

24.【参考答案】 D
【解析】 进程可以包含多个线程,A 错误;同一进程内的多个线程共享进程的用户地址空间,无需依赖内核实现线程间通信,B 错误;C 选项前半句正确,后半句错误,线程是调度的最小单位。

25.下面的叙述中,正确的是( )。
A. 线程的切换,一定会引起进程的切换
B. 线程的切换,不会引起进程的切换
C. 用户级线程的切换,需要操作系统内核支持
D. 内核级线程的切换,需要操作系统内核支持

25.【参考答案】 D
【解析】 同一进程内的线程切换不会引起进程的切换,不同进程内的线程切换会引起进程切换,所以 A、B 均不正确。用户级线程的切换由进程完成,操作系统内核感知不到用户级线程的存在,C 错误。内核级线程的切换需要操作系统内核的支持,D 正确。

26.下面的叙述中,正确的是( )。
A. 一个进程一定包含多个线程
B. 线程是将进程进一步细分的单位,可以脱离进程独立运行
C. 引入线程可以进一步提升进程的并行性
D. 线程间相互 “隔离”,无法直接共享数据

26.【参考答案】 C
【解析】 一个进程可以只包含一个线程,A 错误。线程是对进程的进一步细分,但线程不是资源分配的基本单位,需依靠进程的资源,不能脱离进程独立运行,B 错误。同一进程的多个线程之间能够共享进程的大部分资源,D 错误。

27.下面的叙述中,正确的是( )。
A. 同一进程的多个线程可以并发执行,不同进程的多个线程只能串行执行
B. 同一进程的多个线程只能串行执行,不同进程的多个线程可以并发执行
C. 多线程程序设计上,可以将程序的 I/O 部分和计算部分拆分成两个线程,以发挥线程优势
D. 同一进程的线程间通信代价很低,但线程创建操作的代价和进程创建相似

27.【参考答案】 C
【解析】 同一进程和不同进程的多个线程均可并发执行,A、B 错误。线程创建、销毁的代价低于进程,D 错误。

28.同一进程的不同线程之间,不能共享的是( )。
A. 进程的代码段
B. 进程的全局变量
C. 进程的用户地址空间
D. 进程中各个线程的栈指针

28.【参考答案】 D
【解析】 同一进程内的多个线程共享进程的代码段、全局变量和用户地址空间。线程的栈指针是私有的,存放在线程控制块 TCB 中。

29.下列关于多对一线程模型的论述中,正确的叙述是( )。
A. 指将多个内核级线程映射到一个用户级线程
B. 当一个线程被阻塞时,同一进程内的多个线程均会被阻塞
C. 多处理器操作系统中,同一进程的多个线程可以并行执行
D. 操作系统内核可以感知用户线程的存在

29.【参考答案】 B
【解析】 多对一模型是指将多个用户级线程映射到一个内核级线程,操作系统无法感知多个用户级线程的存在,A、D 错误。由于多个用户级线程只对应一个内核级线程,一个线程的阻塞会导致整个进程的阻塞,B 正确。即使在多处理器操作系统中,多对一线程模型下多个线程也无法并发执行,任意时刻最多只能有一个用户级线程运行,C 错误。

30.针对用户级线程和内核级线程的特点,错误的是( )。
A. 用户级线程实现简单,可以在所有操作系统上实现
B. 用户级线程的调度由进程管理和控制
C. 即使实现了用户级线程,内核调度的对象依然是进程
D. 内核级线程的切换由操作系统内核负责,较用户级线程切换开销更低

30.【参考答案】 D
【解析】 内核级线程的实现依赖操作系统支持,而用户级线程切换在所属进程内完成,无需内核参与,所以内核级线程开销高于用户级线程,D 选项错误。

31.关于内核级线程优缺点的描述中,错误的是( )。
A. 相较于进程,线程切换的系统开销更小
B. 需要操作系统内核支持
C. 线程阻塞会导致该进程的其他线程一同阻塞
D. 在多处理器系统上,同一进程的多个线程可以并行执行

31.【参考答案】 C
【解析】 若一个进程由多个内核级线程构成,其中一个线程阻塞不会致使整个进程阻塞,C 选项正确。

32.关于用户级线程优缺点的描述中,错误的是( )。
A. 操作系统的调度单位依旧是进程
B. 线程间切换代价小
C. 不需要操作系统内核支持
D. 在多处理器系统上,同一进程的多个线程可以实现并行执行

32.【参考答案】 D
【解析】 用户级线程由进程管理,操作系统无法感知,调度单位仍是进程,A 选项正确。相较于进程,线程切换代价小,且用户级线程无需内核支持,切换代价较内核级线程更小,B、C 正确。用户级线程的不足在于多个线程无法并行执行,D 错误。

33.以下描述中,哪个不是多线程系统的特长( )。
A. 利用线程并行地执行矩阵乘法运算
B. Web 服务器利用线程请求 HTTP 服务
C. 键盘驱动程序为每一个正在运行的应用配备一个线程,用来响应相应的键盘输入
D. 基于 GUI 的 debugger 用不同线程处理用户的输入、计算、跟踪等操作

33.【参考答案】 C
【解析】 系统中通常只有一个键盘,且用户键盘输入速度较慢,用一个线程响应键盘输入即可。其余选项可借助线程优势提高效率。

34.用户级线程的优点不包括( )。
A. 线程切换不需要内核态(或系统态)特权
B. 支持不同的应用程序采用不同的调度算法
C. 在不同操作系统上不经修改就可直接运行
D. 同一个进程内的多个线程可以同时调度至多个处理器执行

34.【参考答案】 D
【解析】 用户级线程切换由用户空间的线程库完成,与操作系统内核无关,无需内核态特权,A 正确。用户级线程中,应用程序可自行决定线程调度方式,B 正确。只要有线程库,用户级线程可在任意操作系统运行,无需修改代码,C 正确。用户级线程对操作系统不可见,操作系统以进程为单位调度,这些线程不能在多个 CPU 上同时运行,D 错误。

35.下面的说法中,正确的是( )。
A. 内核级线程和用户级线程的切换需要内核介入
B. 进程是调度的单位,线程是资源分配的单位
C. 进程总是资源分配的基本单位,线程只拥有少量资源
D. 进程总是调度和资源分配的最小单位,线程无法脱离进程运行

35.【参考答案】 C
【解析】 用户级线程切换无需操作系统内核介入,A 错误。进程是资源分配基本单位,引入线程后,线程是调度最小单位,B 错误、C 正确。线程可以是调度最小单位,D 选项前半句错误。

36.下列关于进程和线程的叙述,正确的是( )。
A. 线程间的地址空间互相隔离
B. 线程间可以共享用户地址空间
C. 线程是一部分程序段,多个线程构成一个进程
D. 线程间通信主要利用管道、共享存储、消息传递等机制

36.【参考答案】 B
【解析】 同一进程内的线程共享进程的用户地址空间,A 错误。线程是进程的进一步细分单位,并非简单对代码段的划分,C 错误。D 选项提及的方法主要用于进程间通信,因线程共享进程地址空间,线程间通信更简便,同一进程下的多个线程共享该进程地址空间,B 正确。

37.进程之间通信的机制不包括( )。
A. 共享存储区
B. 管道
C. 消息传递
D. 访问对方进程地址空间

37.【参考答案】 D
【解析】 进程的地址空间相互隔离,进程不能直接访问其他进程的地址空间,D 错误。

38.两个进程协作完成一个任务,不能实现数据传递的手段是( )。
A. 程序段的全局变量
B. 共享数据结构
C. 共享存储区
D. 管道机制

38.【参考答案】 A
【解析】 进程地址空间相互隔离,其他进程无法直接访问某进程的全局变量,A 正确。B、C、D 是进程的通信方式。

39.管道通信是以( )进行写入和读出的。
A. 消息为单位
B. 自然字符流
C. 文件
D. 报文

39.【参考答案】 B
【解析】 管道是特殊文件,读写进程以字符流形式进行读写操作,B 正确。

40.下列关于管道 (Pipe) 通信的叙述中,正确的是( )。
A. 一个管道可实现双向数据传输
B. 管道的容量仅受磁盘容量大小限制
C. 进程对管道进行读操作和写操作都可以被阻塞
D. 一个管道只能有一个读进程或一个写进程对其操作

40.【参考答案】 C
【解析】 管道是半双工的,同一时刻数据只能单向流动,A 错误。管道是固定大小的缓冲区(如 4KB) ,在内核中实现,其大小不受磁盘大小影响,B 错误。管道空时读进程阻塞,满时写进程阻塞,C 正确。一个管道可有多个读进程和写进程,但不能同时进行写操作,D 错误。

41.下面关于进程互斥的论述中不正确的是( )。
A. 信号量是一种进程互斥技术
B. 管程是一种进程互斥技术
C. 消息机制可用于实现进程互斥
D. 消息机制不能支持进程间的互斥

41.【参考答案】 D
【解析】 设置值为 1 的信号量可实现进程互斥,A 正确。管程中每次只允许一个进程进入,实现进程互斥,B 正确。消息缓冲通信中,消息队列是临界资源,通过执行 P、V 操作实现进程互斥,C 正确,D 错误。

2.1.9 真题演练

42.【2010】下列选项中,导致创建新进程的操作是( )。
I. 用户登录成功
II. 设备分配
III. 启动程序执行
A. 仅 I 和 II
B. 仅 II 和 III
C. 仅 I 和 III
D. I、II 和 III

42.【参考答案】 C
【解析】 引发新进程创建的情况主要有:用户登录、高级调度发生、系统响应用户程序请求、现有进程派生。用户登录成功后,操作系统会为其创建进程,I 正确。设备分配无需创建新进程,设置对应数据结构即可,II 错误。启动程序执行会导致新进程创建,III 正确。

43.【2011】在支持多线程的系统中,进程 P 创建的若干个线程不能共享的是( )。
A. 进程 P 的代码段
B. 进程 P 中打开的文件
C. 进程 P 的全局变量
D. 进程中某线程的栈指针

43.【参考答案】 D
【解析】 线程拥有保证自身独立运行的必要资源,线程控制块 TCB 中记录专属堆栈指针,用于保存局部变量和返回地址,对其他线程透明、不可共享,D 正确。

44.【2012】下列关于进程和线程的叙述中,正确的是( )。
A. 不管系统是否支持线程,进程都是资源分配的基本单位
B. 线程是资源分配的基本单位,进程是调度的基本单位
C. 系统级线程和用户级线程的切换都需要内核的支持
D. 同一进程中的各个线程拥有各自不同的地址空间

44.【参考答案】 A
【解析】 无论是否引入线程,进程都是资源分配基本单位,线程拥有少量资源,可访问进程全部资源,A 正确。引入线程前,进程是独立调度基本单位;引入系统级线程后,线程是独立调度基本单位,B 错误。操作系统内核无法感知用户级线程,只能支持内核级线程切换,C 错误。进程有独立地址空间,同一进程的线程共享一个地址空间,D 错误。

45.【2014】一个进程的读磁盘操作完成后,操作系统针对该进程必做的是( )。
A. 修改进程状态为就绪态
B. 降低进程优先级
C. 给进程分配用户内存空间
D. 增加进程时间片大小

45.【参考答案】 A
【解析】 进程向操作系统请求读磁盘后进入阻塞态,I/O 操作完成后需唤醒进程,将其状态转为就绪态。注意题目 “必做” 一词,进程读磁盘操作完成后可做之事众多,如提高进程优先级,但这并非必须。

46.【2014】下列关于管道(Pipe)通信的叙述中,正确的是( )。
A. 一个管道可实现双向数据传输
B. 管道的容量仅受磁盘容量大小限制
C. 进程对管道进行读操作和写操作都可能被阻塞
D. 一个管道只能有一个读进程或一个写进程对其操作

46.【参考答案】 C
【解析】 管道半双工,实现双向传输需两个管道,A 错误。管道是特殊文件,容量一般为内存一页,不受磁盘容量限制,B 错误。管道可多个读、写进程操作,但同一时刻只能一个进程操作,满时写进程阻塞,空时读进程阻塞,C 正确。

47.【2015】下列选项中,会导致进程从执行态变为就绪态的事件是( )。
A. 执行 P(wait)操作
B. 申请内存失败
C. 启动 I/O 设备
D. 被高优先级进程抢占

47.【参考答案】 D
【解析】 执行 P 操作后只会继续运行或被阻塞,不会转为就绪态,A 不符合。申请内存失败进程进入阻塞态,直到有可用内存,B 不符合。启动 I/O 设备后进程自动进入阻塞态直到 I/O 任务完成,C 不符合。被高优先级进程抢占后,进程仍具备运行条件,由运行态转为就绪态,D 符合。

48.【2018】下列选项中,可能导致当前进程 P 阻塞的事件是( )。
I. 进程 P 申请临界资源
II. 进程 P 从磁盘读数据
III. 系统将 CPU 分配给高优先权的进程
A. 仅 I
B. 仅 II
C. 仅 I、II
D. I、II、III

48.【参考答案】 C
【解析】 进程 P 申请临界资源,资源充足则继续执行,不足则进入阻塞态,I 可能。进程 P 从磁盘读数据属 I/O 操作,数据到达前进程 P 处于阻塞态,II 可能。系统将 CPU 分配给高优先级进程,进程 P 进入就绪态,III 错误。

49.【2019】下列关于线程的描述中,错误的是( )。
A. 内核级线程的调度由操作系统完成
B. 操作系统为每个用户级线程建立一个线程控制块
C. 用户级线程间的切换比内核级线程间的切换效率高
D. 用户级线程可以在不支持内核级线程的操作系统上实现

49.【参考答案】 B
【解析】 用户级线程的管理在用户空间完成,操作系统内核感知不到其存在,仅调度进程;内核级线程管理在内核空间,需内核支持,A 正确。操作系统无法感知用户级线程,由进程创建并管理相应线程控制块,B 错误。用户级线程切换在用户空间进行,无需内核介入,比内核级线程切换效率高,C 正确。用户级线程管理依赖进程,引入线程库即可,无需内核支持,D 正确。

50.【2019】下列选项中,可能将进程唤醒的事件是( )。
I. I/O 结束
II. 某进程退出临界区
III. 当前进程的时间片用完
A. 仅 I
B. 仅 III
C. 仅 I、II
D. I、II、III

50.【参考答案】 C
【解析】 本题考查进程状态转换的触发事件。I/O 结束,若此前有进程因申请 I/O 操作受阻而阻塞,CPU 会唤醒该进程,使其由阻塞态转为就绪态,I 符合;某进程退出临界区,若有进程等待临界区资源,则会被唤醒,II 符合;当前进程时间片用完,转换为就绪态,不存在唤醒事件,III 不符合。所以选 C。

51.【2020】下列关于父进程与子进程的叙述中,错误的是 ( )。
A. 父进程与子进程可以并发执行
B. 父进程与子进程共享虚拟地址空间
C. 父进程与子进程有不同的进程控制块
D. 父进程与子进程不能同时使用同一临界资源

51.【参考答案】 B
【解析】 A 选项正确,如父进程创建子进程处理部分数据,父子进程可并发执行。父进程与子进程仅共享代码段和部分资源,虚拟地址空间各自独立,不共享,B 错误。PCB 是每个进程独有的数据结构,父子进程不同,拥有不同的进程控制块,C 正确。判断父子进程相关性质时,可将子进程视作普通进程,若答案对普通进程成立,对子进程也成立,据此可判断 A、C、D 正确。

52.【2021】下列操作中,操作系统在创建新进程时,必须完成的是 ( )。
I. 申请空白的进程控制块
II. 初始化进程控制块
III. 设置进程状态为执行态
A. 仅 I
B. 仅 I、II
C. 仅 I、III
D. 仅 II、III

52.【参考答案】 B
【解析】 进程创建过程:①为进程分配进程标识符(PID)和空白 PCB;②分配所需资源;③初始化 PCB 内容;④若顺利,设进程状态为就绪态,放入就绪队列等待调度;若资源不足,设为阻塞态。申请空白进程控制块对应①,初始化进程控制块对应②、③,I、II 正确。进程创建时状态为就绪态或阻塞态,非执行态,III 错误,故选 B。

2.2 处理器调度与上下文切换

        本节主要围绕着一个核心展开:调度。上下文切换是进程调度的实现方式,在上一节的进程控制小节已经进行过详细讲述,如有遗忘可以重温。考生在学习本节知识的过程中,请先尝试回答下列问题:
(1) 什么是处理器调度?
(2) 为什么要进行处理器调度?

        本节前半部分(调度的概念、时机、方式实现、调度算法的目标)重点在概念的理解与记忆,后半部分(典型调度算法、甘特图)重点在理解概念的基础上运用调度算法分析实际问题。对于重点调度算法,书中设置了多道例题和详细的解析。

请考生在学习过程中尝试回答下列问题(题目可以在各个小节中找到答案):
(1) 什么是抢占式调度算法,什么又是非抢占式调度算法?
(2) 调度算法有没有最优解决策略,在设计调度算法时,设计者看重哪些要素和指标?
(3) 有哪些典型的调度算法?针对这些调度算法,可不可以说出它们各自的优缺点?

2.2.1 调度的基本概念

        宏观上讲,调度的发生意味着竞争的产生,资源不足以让所有需求者同时使用,就必须决定使用的先后次序,这个决定的过程,就是一种调度,可以理解成一种资源分配的行为。在计算机的世界中,也存在着 “珍贵” 的资源,处理器就是其中一种,操作系统需要为处理器实现调度。

1.处理器调度
        在多道程序设计系统中,允许多个进程或线程的存在,那么不可避免地会遇到多个进程或线程同时竞争处理器的情况。例如,计算机只有一个处理器,且有两个或更多进程处于就绪态,竞争就出现了,此时只能选择一个进程上处理器运行。在操作系统中,完成上述选择工作的部分是 “调度程序(scheduler)”,调度程序使用的选择算法称为 “调度算法(scheduling algorithm)”。类似的,线程级别的调度和进程级别的调度有着很大的相似性,许多适用于进程调度的处理方法也同样适用于线程调度。
        【提示】请考生区别 “进程调度” 和 “上下文切换”。调度是一种资源分配的行为,包括了调度程序的决策和上下文切换;上下文切换是调度的实现手段,执行调度程序的决策。

2.三种调度层次
        在多道程序系统中,一个作业从被提交并加入等待队列开始,到运行结束这一过程,可能会发生三种层次的调度,分别是作业调度、内存调度和进程调度,根据调度发生的层次,依次称为高级调度,中级调度和低级调度,如图 2.5 所示。
(1) 高级调度(High Level Scheduling)
        高级调度,又称长程调度或作业调度,调度的对象是外存中等待的作业,行为是将作业由外存调度到内存中。当作业调入内存后,操作系统会为该作业创建进程,分配所需资源,执行进程初始化的一系列操作。高级调度能够限制同时运行的进程数量,避免低级调度开销过大;也能根据系统当前的 CPU 和 IO 利用率选取合适的计算密集型或 I/O 密集型作业,以免资源竞争过于激烈或某项资源利用率过低。
        从调度对象可以知道,这种调度主要是针对批处理系统的,分时操作系统和实时操作系统不涉及该层次调度。一个作业只会有一次调入和一次调出,两次的时间差就是作业执行完毕所花费的时间,所以这种调度的频率是最低的。

(2) 中级调度(Intermediate Scheduling)
        中级调度,又称内存调度,该调度的对象是暂时不能运行的进程,行为是将目标进程的相关数据在内存和外存间移动。在现代操作系统中,这种调度实际上是换页功能的一部分。如果当前运行中的进程已经占用了大量内存(系统缺页率过高),那么中级调度就会将部分进程切换为对应的挂起状态。挂起状态的进程不参与低级调度,同时页面置换机制也会倾向于将这些进程使用的内存页面换入磁盘中,这就缓解了内存紧张的问题,进而提高内存利用率和系统吞吐量。中级调度还会在适当的时机激活此前挂起的进程,使其重新参与调度。这种调度一般发生在系统内存资源不足的情况下,所以发生频率要根据计算机内存资源多少和当前内存中进程所占资源多少两个因素共同确定。
        【拓展】中级调度中涉及进程的就绪挂起态和阻塞挂起态,考生结合图 2.6 了解即可。当进程从内存被调入外存时,如果调入前进程状态为就绪态,则调入后进程状态转换为就绪挂起态;如果调入前进程状态为阻塞态,则调入后进程状态转换为阻塞挂起态。我们将引入了挂起状态的模型称为七状态模型。

(3) 低级调度(Low Level Scheduling)
        低级调度,又称进程调度,调度的对象是进程(或内核级线程),行为是决定将处理器资源先分配给哪个进程。根据选用的进程调度算法,调度程序会决定就绪队列中的哪个进程应获得处理器资源,并由分派程序将处理器分配给被选中的进程。进程调度是最基本的一种调度,是发生频率最高的调度,多道批处理、分时和实时操作系统中,都要实现进程调度。在典型调度算法一节,我们会重点讨论这一级别的调度。

三级调度的总结对比如表 2.7 所示。

表 2.7 三级调度对比

调度层次

调度目标

发生频率

进程状态的改变

高级调度

将作业由外存调度到内存中,为其创建进程

作业→创建态→就绪态

中级调度

将进程数据暂存在辅存中(或恢复到内存中)

就绪态→就绪挂起态;阻塞态→阻塞挂起态

低级调度

调度进程轮流使用处理器

就绪态→执行态

2.2.2 调度的时机

调度发生于以下几种情况:
(1) 创建一个新进程之后。当创建完进程后,调度程序需要决定是运行当前进程还是运行其父进程,两个进程都是处于就绪态的,可以调度其中任意一个进程。
(2) 进程退出后。在一个进程退出后,其占有的资源会被释放,可以立即供其他进程使用,所以需要执行调度。
(3) 进程时间片用尽。当前进程放弃处理器,调度程序从就绪队列中选择进程进行调度。
(4) 可抢占式系统中进程进入就绪队列。
        【举例】可抢占优先级调度算法中,有优先级更高的进程进入就绪队列时,会发生调度,由优先级最高的进程占有处理器;可抢占式短进程优先调度算法中,有进程进入就绪队列且该进程要求的运行时间少于目前占有处理器进程的剩余运行时间时,会发生调度。
(5) 阻塞发生时。当一个进程在执行的过程中发生了让其阻塞的情况,例如 I/O 操作、信号量阻塞等等。为了不浪费资源,可以进行调度,选择其他的就绪进程运行。
        【提示】当阻塞发生时,阻塞的原因对调度是有指导意义的。考虑PA​、PB​两个进程。PA​因为尝试访问临界区而被阻塞,此时PB​正在临界区内执行,那么调度程序可以选择先调度PB​,从而更快 “唤醒”PA​来继续执行任务。
(6) I/O 中断发生时。当 I/O 中断发生时,需要进行调度。
        【举例】进程PA​因为申请 I/O 操作而被阻塞。当 I/O 设备执行完毕PA​安排的工作,就可以选择唤醒阻塞的PA​,让其继续执行。当然,也可以不进行调度,让当前占据处理器的进程继续执行。

        大多数情况下,调度和进程切换都会立即执行;但下列情况下并非如此,需要等待对应事件结束后才能进行调度和进程切换。
(1) 中断处理过程中。中断发生后,需要将待恢复数据(PC、PSW、通用寄存器等)保存在被中断进程的核心栈中,如果此时发生调度或上下文切换,会导致中断无法恢复。
(2) 原语执行过程中。原语的执行具有不可中断的特性。

2.2.3 调度的方式

        调度的方式分为非抢占式调度和抢占式调度,主要区别在于操作系统能否 “违背” 一个进程的意愿,主动打断其运行并将处理器资源分配给其他进程。

1.非抢占式调度
在非抢占式调度中,操作系统选择一个进程并让其运行,直到其发生阻塞或者完成任务释放资源为止。在这种调度策略下,进程自愿进入等待状态或终止时发生调度。
(1) 调度发生的时机:
        (a) 进程运行完毕,放弃处理器的使用权。
        (b) 进程发生某种事件而无法继续运行,放弃处理器使用权。
        (c) 进程发生阻塞需要等待继续运行的条件,放弃处理器使用权。
(2) 非抢占式调度的优点:
        (a) 调度算法设计更简单,调度成本更低(例如,没有执行态与就绪态之间的转换开销)。
        (b) 高吞吐的调度策略。
        【提示】调度行为本身,是一个 “白白” 消耗系统资源的行为,因为调度程序占用处理器资源这一行为对作业的完成是没有任何贡献的。抢占式调度会触发更多次的调度,因而系统整体的吞吐量会变低。

2.抢占式调度
        抢占式调度算法中,系统可以根据某种调度的原则,暂停一个进程的执行并将处理器资源分给另一个进程。抢占式调度算法使得系统可以实现实时交互,但是更复杂的实现会带来更大的系统开销。
(1) 抢占遵循的常用原则:
        (a) 优先级:优先级高的进程可以抢占优先级低的进程,这个抢占行为可以发生在进程调度的时机上。例如,当有新进程被加入就绪队列中,如果它拥有比当前运行进程更高的优先级,则可以抢占。
        (b) 短进程优先:请求处理器时间短的进程,可以抢占请求时间长的进程,同样的,这个抢占行为发生在可以进程调度的时机。
        【提示】这种情况下,可以认为进程要求时间的长短决定了进程优先级的高低。
        (c) 时间片轮转原则:每个进程依次占用处理器资源,一个进程耗尽当前分配的时间片后,其他就绪进程可以在进程调度发生时进行抢占,被抢占的进程如果未运行完毕,则会转换为就绪态,进入就绪队列,等待下一次使用处理器资源。
(2) 抢占式调度的优点:
        (a) 抢占式调度方法,可以防止一个进程长时间独占处理器的恶意行为。
        (b) 与非抢占式调度相比,处理器利用率更高。
        (c) 抢占式调度的等待时间和响应时间更短,用户体验好,有利于实时系统和分时系统。
        (d) 每次中断后都需要考虑调度,这使得操作系统更加灵活(对比非抢占式系统需要严格执行到一个程序的结束或阻塞)。
        (e) 操作系统确保所有正在运行的进程的处理器使用率相似,改善了平均响应时间。

2.2.4 调度算法的目标

        调度算法没有最优解。不同情况下,人们根据需要选择不同的调度算法。用户看重的指标不一样,因而对调度算法优化的方向也不同。这里针对几种操作系统介绍其应用环境和典型的调度算法。

1.操作系统的使用场景

        (1) 批处理系统:常用于商业领域,用来处理存货清单等周期性作业。这类系统无需与用户交互,目标是尽快完成作业,因此对调度算法要求平均周转时间短、系统吞吐率高、处理器利用率高。在这种情况下,非抢占式调度策略和不把响应时间作为首要考虑目标的抢占式调度算法都可考虑。这些调度算法降低调度频率和每次执行调度算法的开销,从而提升 CPU 利用率和吞吐量。

        (2) 分时系统:常用于个人电脑等需频繁与用户交互的领域。用户希望快速得到响应,因此应优先考虑响应时间短的调度算法。

        (3) 实时系统:如股票交易系统、航天器自动控制系统等。此类系统为保证任务在规定时间内完成,需要特殊设计的调度算法,且抢占式调度算法居多。

2.调度算法的指标
        以下指标从不同角度评价调度算法,不同调度算法围绕其中一个或多个指标设计。部分指标关注调度算法性能,可量化;部分难以量化。

(1) 资源利用率:为提高计算机资源利用率,应让各种资源处于忙碌状态。处理器资源重要,其利用率计算如公式 2.1:

(2) 周转时间:指作业(进程)从提交到完成消耗的时间,包括等待高级调度、在就绪队列等待、运行和 I/O 耗时。周转时间短,用户能更快得到结果,操作系统希望平均周转时间最短,体现更高效率。

(a) 周转时间T,作业从提交到完成的时间,公式 2.2,tfinish​表示作业完成时间,tarrive​表示作业到达时间。

(b) 平均周转时间Tˉ,公式 2.3,其中n表示作业总数,Ti​表示作业i的周转时间。

(c) 带权周转时间W,作业周转时间T与实际运行时间ts​之比,公式 2.4​。

(d) 平均带权周转时间Wˉ,综合考虑每个作业带权周转时间,公式 2.5,Ti​表示进程i的带权周转时间,ti​表示操作系统为进程i提供的服务时间。

【提示】带 “平均” 的指标描述调度算法整体性能,其他指标描述特定进程性能。典型调度算法小节会用 FCFS 和 SPF 算法举例计算。

(3) 吞吐量:指单位时间内完成的作业数,受运行作业长度影响,短作业多则系统吞吐率高。

(4) 响应时间:用户提交请求开始,直到系统首次对作业做出响应所花费的时间。分时操作系统中是重要衡量指标,低响应时间给用户更好体验。

(5) 等待时间:进程在队列中等待资源的时间,等待时间 = 周转时间 - 运行时间。对用户和操作系统而言,平均等待时间长都不利,反映调度算法设计欠佳。

难以量化的指标则包括:

(1) 公平性:相似进程应获相似服务,如获得合理处理器时间,避免进程长时间得不到处理器资源(饥饿)。需注意 “相似” 是相对的,有些调度算法为进程定义不同优先级,先调度高优先级进程。

(2) 平衡性:指处理器密集型作业和 I/O 密集型作业的调度平衡,保证计算机各资源尽可能忙碌。

        【提示】特殊用途操作系统还需考虑特殊指标,如移动设备能耗、实时系统实时性等。

        综上,好的调度算法需考虑操作系统应用场景、用户偏好、系统运行效率等。典型调度算法一节将讨论不同算法的目标、优缺点和适用场景。

2.2.5 调度的实现

1.调度的主要任务
进程调度需完成三点任务:

(1) 保存处理器现场信息。上下文切换后其他进程会使用这些资源,需提前将处理器上的程序计数器、通用寄存器等寄存器内容保存在进程控制块中。

(2) 按进程调度算法确定下一个分配处理器的进程,将其状态改为执行态,准备分配处理器资源。

(3) 将处理器资源分配给进程,根据进程控制块信息恢复其运行环境,使其能从上一次中断的断点继续运行。

2.进程调度机制


为实现上述任务,进程调度机制应包含以下三个部分:

(1) 排队器:进程调度系统中,根据进程不同状态维护多个进程队列,如就绪队列、阻塞队列。调度时通过这些队列快速选择下一个分配处理器资源的进程。排队器在进程状态转为就绪态时,将其插入就绪队列。

(2) 分派器:根据进程调度程序选择的进程,从就绪队列取出并分配处理器资源。

(3) 上下文切换器:分配处理器给新进程时进行上下文切换。操作系统先保存当前使用处理器进程的上下文到进程控制块,装入分派程序上下文保证其运行,再取出下一个要分配处理器的进程,从分派程序上下文转换到该进程上下文,使其开始运行。

3.闲逛进程(Idle Process)
        闲逛进程无明确工作,用于解决调度特殊情况。就绪队列无其他进程可调度时,系统调用闲逛进程使用处理器,运行中检查中断是否发生。闲逛进程优先级最低,有其他进程进入就绪队列就会引发处理器调度。
【提示】Unix 操作系统下 PID 为 0 的进程就是闲逛进程。

4.两种线程的调度

(1) 用户级线程调度:此方式下,由各个进程管理其包含的线程,操作系统内核感知不到线程存在,调度仍以进程为单位。进程获得处理器后,利用进程内调度程序调度各个用户级线程运行。

(2) 内核级线程调度:该方式下,由操作系统管理各个线程并调度,需内核参与,增加额外开销。好处是线程阻塞不会导致同属一个进程的其他线程阻塞,且能利用多处理器技术。

2.2.6 CPU 调度算法

        处理器调度层次有三个层次的调度,以下介绍典型 CPU 调度算法,即三个层次调度中调度算法的具体实现。部分算法适用于多种层次调度,如先来先服务调度算法。

1.先来先服务调度算法(First - come First - serve, FCFS)
        FCFS 是最简单朴素的算法,也叫先进先出算法(First In First Out, FIFO),适用于作业调度和进程调度。作业调度时,系统按作业放入外存队列顺序依次调入内存执行;进程调度时,从就绪队列选最先进入的进程,转为执行态并分配处理器资源,直到下一个调度时机。该算法虽不会成为操作系统主要调度算法,但一些复杂调度算法(如优先级队列调度算法)包含其思想。

(1) 优点:逻辑简单。

(2) 缺点:①效率差;②无法实现人机交互;③未考虑进程间差异,如进程紧急程度;④更偏向处理器密集型进程和长进程。

        【提示】FCFS 算法偏向长进程和处理器密集型进程原因:长进程排队并使用处理器直到作业完成或阻塞,使用处理器时间长;I/O 密集型进程遇 I/O 操作会阻塞重新排队,处理器密集型进程阻塞少,排队次数少,等待时间也会少。

        【例 2.1】有P1​,P2​,P3​,P4​,P5​五个进程,其到达时间和执行时间如表 2.8 所示。在单处理器且使用 FCFS 算法的情况下,分析该调度算法的各项指标。分析系统吞吐率时,每个进程对应一个作业,进程完成意味着作业完成。

2.短进程(作业)优先调度算法
        短进程(作业)优先调度算法,适用于作业调度和进程调度。进程调度时称短进程优先调度算法(Shortest Process First, SPF),依据就绪队列中进程预估的处理器使用时间,每次调度选剩余处理器使用时间最短的进程;作业调度时称短作业优先调度算法(Shortest Job First, SJF) ,按外存队列中作业要求的执行时间调度,选预估剩余处理器使用时间最短的作业。

(1) 优点:相较于 FCFS,性能有所提升,SPF 的平均等待时间和平均周转时间最优。

        【提示】实际上 SPF/SJF 是较为理想的调度算法,但现实中难以实现,主要原因有二:一是进程难以准确预估运行所需时间;二是程序可能谎报运行时间恶意竞争处理器使用权。不过该算法可作为评测其他调度算法优劣的标杆。

(2) 缺点:①算法需进程(作业)预估运行时间,可能出现估算不准或进程 “谎报” 时间的问题;②该算法偏向短进程,若等待调度过程中不断有短进程创建,长进程可能被无限期搁置,产生饥饿现象;③算法仅依据进程(作业)耗时长短分配处理器,未考虑进程间的差异性。

根据是否可抢占,短进程调度算法分为:

(1) 非抢占式短进程优先调度算法:调度时,选择当前就绪队列中要求处理器时间最少的进程分配处理器,该进程运行期间不会被抢占,直至主动放弃处理器。

(2) 抢占式短进程优先调度算法:调度时,选择当前就绪队列中要求处理器时间最少的进程分配处理器。若该进程运行时,就绪队列出现要求时间更短的进程,此进程会被抢占处理器资源,当前运行进程状态转为就绪态。

【提示】部分教材对上述两种情况做更细致区分,SPF 专指非抢占式短进程优先算法,抢占式算法称最短剩余时间优先调度算法(Shortest Remaining Time, SRT),因为抢占式算法比较的是进程剩余执行时间。分析题目时,要留意调度算法名称及是否可抢占的描述。

【例 2.2】有P1​,P2​,P3​,P4​,P5​五个进程,其到达时间和执行时间如表 2.8 所示。在单处理器且使用 SPF(非抢占式)算法的情况下,分析该调度算法的各项指标。

【例 2.3】有P1​,P2​,P3​,P4​,P5​五个进程,其到达时间和执行时间如表 2.8 所示。在单处理器且使用 SPF(抢占式)调度算法的情况下,试求这 5 个进程的平均周转时间。

        计算过程中,可以利用甘特图确定各个进程的结束时间(Tfinish​),各个进程的到达时间(Tarrive​)是已知的,利用T=tfinish​−tarrive​计算出各个进程的周转时间;各个进程执行时间(Ts​)是已知的,继续使用W=ts​T​计算出各个进程的带权周转时间;最后按题目要求算出这五个进程的平均带权周转时间即可。计算完毕后,考生可以思考这样一个问题,短进程优先调度算法的两种形式(可抢占式、不可抢占式)的性能哪种更好,为什么是这样?

        关于甘特图的知识,可以参见甘特图小节。在分析进程调度算法时,主要考虑处理器个数和调度算法特征。通过上面的例题,请考生注意区分短进程优先调度算法中,可抢占和不可抢占的情况。关于调度相关的知识,难点主要在于计算,考生可以继续利用表 2.8 数据和其他调度算法去计算 2.2.3 小节中调度算法的各个指标。
3. 优先级调度算法(Priority - scheduling Algorithm, PSA )
        优先级调度算法,可用于作业调度、进程调度。前两种调度算法未考虑进程间差异性,PSA 则为解决该问题而提出。此算法下,作业(进程)优先级由外界赋予,系统依此进行调度。

        【举例】对于紧急进程,可设更高优先级,下次进程调度时,系统优先为其分配处理器资源。作业调度时也如此,系统从外存队列挑选优先级最高作业,装入内存,创建进程分配资源,设进程状态为就绪态,放入就绪队列。

根据是否可抢占,优先级调度算法分为以下两种:

        (1) 非抢占式优先级调度算法:每次分配处理器的进程会持续运行至释放处理器资源,如程序运行完毕或因某些事件退出等,此时调度程序选等待队列中优先级最高程序分配时间片。

        (2) 抢占式优先级调度算法:每次选最高优先级进程分配处理器资源,若进程运行中就绪队列出现更高优先级进程,该进程会抢占处理器资源,当前运行进程状态由执行态变为就绪态。

在调度程序运行过程中,根据优先级是否动态变化,分为静态优先级和动态优先级。

(1) 静态优先级:指各进程优先级在调度程序运行初始就确定,运行期间不变。设计优先级一般依据以下几点:

        (a) 系统进程优先级通常高于用户进程优先级。

        (b) I/O 密集型进程优先级高于处理器密集型进程。

        (c) 对资源要求少的进程优先级高于对资源要求多的进程。

        (d) 用户自定义优先级。

(2) 动态优先级:指调度程序运行中,各进程优先级动态变化。下面将提到的高响应比优先调度算法,就通过考虑进程等待时间实现动态优先级。

4.高响应比优先调度算法(Highest Response Ratio Next, HRRN )
        高响应比优先调度算法,适用于作业调度、进程调度。该算法综合考虑进程(作业)等待时间和运行时间来调度。根据公式 2.6 确定进程(作业)优先级。可看出,因等待时间变化,优先级也动态变化,进程等待时间增加,优先级变高,更易被调度。不难发现,两进程要求时间相同时,优先级由等待时间决定,符合 FCFS 算法;两进程等待时间相同时,短进程优先级更高,类似 SJF,有较好平均等待时间和平均周转时间,且不会出现饥饿现象,长进程等待足够时间,优先级会高于短进程。

5.时间片轮转(Round Robin, RR )调度算法

        RR 算法将处理器使用时间划分成一个个时间片,公平地分给每一个等待处理器资源的就绪进程,时钟中断发生时,系统会修改当前进程在时间片内的剩余时间,当一个进程分配的时间片耗尽后,其会重新进入就绪队列等待下一次分配时间片。该算法可以适用于分时操作系统中的进程调度。系统会将所有就绪进程按照 FCFS 算法来维护就绪队列,每个时间片结束后操作系统都会结束当前进程,并调度下一个就绪程序运行。在这种策略下,每个进程都能公平地使用处理器资源,也保证了进程的响应时间。

①RR 算法的调度时机:

(1) 一个时间片耗尽,在时钟中断发生时,调度程序调度下一个就绪进程上处理器运行,将当前进程放回到就绪队列末尾。

(2) 一个时间片未耗尽,但进程已完成工作,或因阻塞等原因放弃处理器资源,调度程序会选择下一个就绪程序进行进程调度。

②时间片大小的确定:
        RR 算法涉及对于时间片长短的选择,这对于 RR 算法的性能有着巨大的影响。当时间片很小时,操作系统需要频繁地进行进程调度,大大增加系统开销,使整体性能变差。当时间片足够大,使得每个进程只用一个时间片就可以完成任务时,该算法就退化成了 FCFS 算法。影响时间片大小的主要因素包括响应时间、系统开销和进程数量等,设计一个合理的时间片大小应该考虑各个进程的实际情况,使得每个进程在一个时间片内,至少可以完成一次交互。

6.多级队列调度算法
        多级队列调度算法,可以适用于进程调度。该算法将就绪队列设置为多个,根据就绪进程的特点和类型,将其分配在不同的就绪队列中。针对每个就绪队列,可以采用不同的调度算法。例如,每个队列选择上述调度算法的一种,这种调度算法,不但可以凸显出各种调度算法的优势,也能在一定程度上弥补这些算法的缺点。在多处理器系统中,可以利用该调度算法,为每个处理器资源指定一个就绪队列,这样既可以根据进程类型和紧急程度等因素为进程分配更合理的就绪队列,还有利于需要多组线程或进程协作完成任务的情况,即将这些线程或进程分配到不同的就绪队列中,使得它们可以同时获得处理器资源。

7.多级反馈队列(Multilevel Feedback Queue)调度算法
多级反馈队列调度算法,可以适用于进程调度,这种调度算法能够较好地满足各类进程对于处理器资源的需求,是公认较好的一种调度算法。

①算法实现过程:

(1) 该算法将就绪队列分成多个,为这些队列依次分配递减等级的优先级。第一个就绪队列拥有最高的优先级,第二个就绪队列的优先级次于第一个就绪队列,以此类推。在每个就绪队列中,根据该队列的优先级,划分大小不同的时间片,高优先级的队列中,时间片小,低优先级的队列中,时间片大。
        【提示】有时间片并不意味着是时间片轮转算法,因为进程在运行完一个时间片的时间后,会被放入下一级就绪队列而不是当前队列中。关于时间片大小的确定,一般来说,第一级队列的时间片大小能够满足大多数进程人机交互所需要的时间即可,后续队列的时间片可以按照每级增加一倍的规律增长。

(2) 当一个作业的进程被创建并分配资源后,先将其加入第一个队列的末尾,依据 FCFS 算法等待分配时间片。如果该进程被调度执行后在一个时间片内未完成其任务,将会被降级到下一个队列,重新进行上述过程,直到进程被降级到最低优先级的队列中。此时进程不会继续降级,将在该就绪队列中遵循时间片轮转调度算法等待调度。

(3) 按照队列的优先级进行调度。等级高的就绪队列中的进程会被优先调度,对于第 i 级队列,只有当 1 到 i - 1 队列中不存在就绪进程,才可以调度该队列中进程。如果当前使用处理器资源的进程来自第 i 级队列,而此时第一级队列中进入了新的就绪进程,那么会立刻进行抢占式进程调度,并将此时正在运行的程序放回 i 级队列队尾。

②多级反馈队列调度算法如何满足各类用户:

(1) 终端型用户:多为交互型作业,所需时间较少,大多数在第一级队列中就能快速完成,而第一级队列具有最高的优先级,这样使得任务的周转时间短。

(2) 短批处理作业用户:作业长度稍长,在前几级队列中就可以完成,周转时间较短。

(3) 长批处理作业用户:作业长度长,但是也会在前几级队列中等待并获得时间片,执行部分程序,不会长时间得不到执行。

8.调度算法对比

                                                        表2.13 调度算法对比2

调度算法

特点

先来先服务

优点:逻辑简单
缺点:完全不考虑进程特点
利于:长进程、处理器密集型进程
不利于:短进程、I/O 密集型进程

短进程优先

缺点:进程预计运行时间难以计算
优点:拥有最优的平均等待时间和平均周转时间
利于:短进程
不利于:长进程

优先级

通过设置进程优先级以区分进程特点
利于:高优先级进程
不利于:低优先级进程

高响应比优先

优先级动态变化,利于短进程但可以消除饥饿
利于:短进程
不利于:长进程

时间片轮转

公平的将处理器分配给每个进程

多级反馈队列

能较好满足各类进程对处理器的需求
长进程、I/O 密集型进程随着运行会逐步下沉到低优先级队列

2.2.7 甘特图

        甘特图(Gantt chart),由亨利・劳伦斯・甘特(Henry Laurence Gantt)提出,用于显示和管理项目的进度。本节我们学习甘特图以辅助解题,甘特图在分析进程调度、多进程并发执行等场景时,有着直观清晰的优点。
在设计一个甘特图时,要通过进程列表(并发执行的进程)和时间刻度表示出特定行为(输入、运行等)的顺序与持续时间。一个典型的甘特图中,横轴表示时间,一个块表示一个单位的时间;纵轴表示进程,可以清晰地看到某个进程开始执行和结束的时间;线条的不同花纹表示不同的任务,这些任务的执行需要计算机硬件的支持。分析场景时,可以将描述中资源、进程、任务三个要素抽取出来,对应甘特图的三个维度。
        【提示】下面提到的 “单资源” 是指同类型的资源只有一个。例如现有一个处理器和一个输出设备,即是 “单资源” 的情况,在单资源情况下,使用每种资源时都要保证不能有重叠。
甘特图有如下三种场景:

①场景 A:多进程单任务单资源

        (1) 资源:一个处理器,运行先来先服务调度算法(FCFS)。

        (2) 进程:有三个进程 {A,B,C},分别在 0 时刻、5 时刻和 6 时刻进入就绪队列。

        (3) 任务:每个进程均预计使用处理器运行 4 个时间单位。

        (4) 甘特图:如2.13所示。

②场景 B:多进程多任务单资源

        (1) 资源:一个处理器,运行先来先服务调度算法(FCFS);一个输出设备。

        (2) 进程:有两个进程 {A,B},分别在 0 时刻、3 时刻进入就绪队列。

        (3) 任务:每个进程均预计使用处理器运行 4 个单位时间,之后使用输出器 2 个单位时间进行输出。

        (4) 甘特图:如图 2.14 所示。

③场景 C:多进程多任务多资源

        (1) 资源:两个处理器,均运行先来先服务调度算法(FCFS);一个输出设备。

        (2) 进程:有两个进程 {A,B},分别在 0 时刻、3 时刻进入就绪队列。

        (3) 任务:每个进程均预计使用处理器运行 4 个单位时间,之后使用输出器 2 个单位时间进行输出。

        (4) 甘特图:如图 2.15 所示。

【例 2.4】某单 CPU 系统中有输入和输出设备各 1 台,现有 3 个并发执行的作业,每个作业的输入、计算和输出时间如下表所示,则执行完 3 个作业需要的时间最少是 ( )。

A. 15ms        B. 17ms        C. 22ms        D. 27ms

解:选 B。甘特图如图 2.16、2.17、2.18 所示,多种执行方式均可以在 17ms 内执行完毕。

2.2.8 多处理机调度

        【提示】此部分内容是 2025 考研 408 大纲中新增的内容,以概念的了解记忆为主。其实真的不难,耐心看一遍,应该就能理解。

        多处理机系统 MPS(MultiProcessor System)指由多个处理机(CPU)通过高速总线或通信线路等互连技术,共享输入 / 输出设备、主存储器等资源,在统一的操作系统控制下,协同工作的计算机系统。

        多处理系统 MPS 具有增加系统吞吐量、节省成本(达到相同的处理能力,n 个处理机比 n 台独立计算机更节省成本)、提高系统可靠性(某个 CPU 故障,系统依然可以正常运行)等优点。

多处理机系统 MPS 的类型

(1) 根据系统中处理机的结构和功能,将多处理系统 MPS 分为对称和非对称 2 种类型:

        ①对称多处理机系统 SMP(Symmetric MultiProcessor System):系统中所用 CPU 在硬件结构和功能上都是相同的,各 CPU 之间地位平等,不存在主从之分。目前绝大部分的 MPS 属于 SMPS。

        ②非对称多处理机系统 ASMP(Asymmetric MultiProcessor System):在系统中存在多种硬件结构和功能上不同的 CPU,CPU 之间存在主从之分。

(2) 根据系统中各处理机之间是否相互独立,将多处理系统 MPS 分为紧密耦合和松弛耦合 2 种类型:

        ①紧密耦合 MPS:由操作系统集中统一管理系统中的资源,多处理机通过高速总线互连。

        ②松弛耦合 MPS:各处理机(或计算机)之间相对独立,通过通信线路互连。

2.多处理机系统的进程调度
        多处理机系统中的进程调度与系统结构相关。对于对称多处理机系统,因为 CPU 都是相同的,进程被调到任一处理机上均可。对于非对称多处理机系统,要选择合适的 CPU 运行进程。

3.多处理机系统的进程分配方式

(1) 对称多处理机系统(SMP)中的进程分配方式
        在 SMP 系统中,将所有处理机组织成一个处理机池,选择处理机池中的处理机分配给进程,有以下 2 种分配方式:

        ①静态分配:一个进程在其生命周期内被固定分配到同一个处理机上运行。这种方式的优点是系统开销小,缺点是各处理机之间可能会忙闲不均。

        ②动态分配:一个进程在其生命周期内被随机分配到处于空闲的处理机上运行。这种方式解决了各处理机间忙闲不均的问题。并且,对于紧密耦合 MPS 不会增加开销,而对于松弛耦合 MPS 会增加开销。

(2) 非对称多处理机系统中的进程分配方式
非对称 MPS 大多采用主从式结构,由主机负责进程调度,从机负责运行用户程序。

4.多处理机系统的进程 / 线程调度方式

        (1) 自调度方式:处理机在空闲时,从公共的就绪队列(整个系统中只设置一个)中选择进程 / 线程来运行。可沿用单处理机环境中的调度算法(例如:先来先服务 FCFS)。其缺点是存在系统瓶颈、效率低、线程切换频繁等问题。

        (2) 成组调度方式:将同属于一个进程的一组线程同时分配到一组处理机上运行。为了解决自调度方式中线程切换频繁的问题而提出的,其调度性能比自调度方式更好。成组调度中处理机时间的分配有以下 2 种方式:

        ①给所有进程(应用程序)平均分配处理机时间:对于含有 n 个处理机和 m 个进程(应用程序)的系统,每个进程最多有 n 个线程,则分配给每个进程去占用 n 个处理机的时间最多为m1​。

        ②给所有线程平均分配处理机时间,比按进程分配更高效。

(3) 专用处理机分配方式:进程在其生命周期内被分配一组专用的处理机。

(4) 动态调度:进程的线程数量在运行期间可以动态变化。操作系统负责给作业分配处理机,作业再负责将得到的处理机分配给对应的任务线程。缺点是调度开销大。

2.2.9 习题精编

1.某单处理器系统支持多道程序设计,若此刻有多个就绪态进程,则下列叙述中错误的是( )
A. 进程调度的目标是让进程轮流使用处理器
B. 当一个进程运行结束后,会调度下一个就绪进程运行
C. 上下文切换是进程调度的实现手段
D. 处于临界区的进程在退出临界区前,无法被调度

1.【参考答案】D
【解析】当一个临界区内有进程,则其他想要进入该临界区的进程会被阻塞,不进入该临界区的进程依然可以被调度;一个进程退出临界区前,可以发生调度,只是调度对象不能是要进入该临界区的进程,故 D 选项错误。

2.下列各级调度中,发生频率最高的是( )。
A. 低级调度
B. 中级调度
C. 高级调度
D. 三者发生频率相近

2.【参考答案】A
【解析】低级调度,又称进程调度,该调度的对象是进程(或内核级线程),行为是决定将处理器资源分配给哪个进程。根据选用的进程调度算法,调度程序会决定就绪队列中的哪个进程应获得处理器资源,并由分派程序将处理器分配给被选中的进程。进程调度是最基本的一种调度,是发生频率最高的调度,所以 A 选项正确。

3.下列场合中,一定会发生调度的时机有( )。
I. 新进程被创建时
II. 进程运行完毕
III. 可抢占式系统中高优先级进程进入就绪队列
IV. 时间片耗尽
V. 进程运行中发生错误
A. I、II、III 和 IV
B. II、III、IV 和 V
C. I、III、IV 和 V
D. 全部都是

3.【参考答案】B
【解析】一个新进程被创建,可以是调度的时机,但并不是一定,I 错误。II、III、IV、V 四种情况,都是运行的进程主动或被动放弃处理器,需要调度下一个就绪进程。

4.在非剥夺调度方式下,必定会引起进程调度的情况是( )。
A. 一个新进程被创建
B. 一个进程从执行态进入阻塞态
C. 一个进程从阻塞态进入就绪态
D. 一个进程从就绪态进入阻塞态

4.【参考答案】B
【解析】题目条件要求在非剥夺调度方式下,所以 A、C 不正确;倘如在剥夺调度方式下,A、C 选项陈述的时机是有可能发生调度的。一个进程阻塞后,必须要调度进程,所以 B 选项正确;D 选项的情况不会发生,就绪态进程无法直接进入阻塞态。

5.下列调度算法中,一定是抢占式调度的是( )。
A. 时间片轮转
B. 先来先服务
C. 优先级
D. 短进程优先

5.【参考答案】A
【解析】先来先服务一定是非抢占式,时间片轮转一定是抢占式,优先级和短进程优先既可以是非抢占的,也可以是抢占的。

6.下列调度算法中,既可以设计成抢占式调度,也可以设计成非抢占式调度的是( )。
A. 短进程优先
B. 优先级
C. 高响应比优先
D. A、B、C 均可

6.【参考答案】D
【解析】A、B、C 均可设计成抢占式和非抢占式调度算法,高响应比优先和短进程优先都可以理解成优先级的一种实现方式。考生可以思考一下各种调度算法设计成可抢占式和非抢占式的区别,再翻看知识点解析检查。

7.以下哪些指标是调度算法设计时可以考虑的( )。
I. 公平性
II. 资源利用率
III. 互斥性
IV. 平均周转时间
A. I、II
B. I、II、IV
C. I、III、IV
D. 全部都是

7.【参考答案】B
【解析】互斥性不是调度算法考虑的,III 排除;调度算法的目标是更好地选取下一个运行的进程,一般考虑公平性、资源利用率、平衡性、周转时间、系统吞吐率、响应时间和等待时间等因素,所以选择包含 I、II、IV 的 B 选项。

8.下列关于时间片轮转调度算法的叙述,错误的是( )。
A. 考虑了调度的公平性
B. 能够及时对多个用户做出响应
C. 系统的平均周转时间是最优的
D. 每次时间片耗尽时,会进行调度

8.【参考答案】C
【解析】系统平均周转时间最优的调度算法是短进程优先调度算法。A、B、D 三个选项都是时间片轮转调度算法的特点。

9.下面关于调度算法的叙述中,不正确的是( )。
A. 可以提高处理器利用率
B. 可以提高设备利用率
C. 进程调度发生地越频繁,系统吞吐量越高
D. 调度算法需要对多个指标进行折中

9.【参考答案】C
【解析】进程调度程序本身也是需要占用处理器资源的,如果调度程序运行得太过频繁,反而不利于增加系统吞吐量,可以理解为调度程序抢占了本该属于进程运行的计算机资源,所以 C 选项错误。

10.一个单处理器单道操作系统上,有 4 个作业,到达时间和执行时间如下表所示,调度算法选用先来先服务。求系统平均周转时间( )。

A. 2
B. 3.5
C. 4.5
D. 8

10.【参考答案】C
【解析】平均周转时间为每个进程周转时间的平均值。先求出各个进程的周转时间,再求平均值即可。本题答案为(2+4+5+7)/4=4.5。

11.关于进程优先级的论述中,错误的是( )。
A. 系统进程的优先级一般高于用户进程
B. I/O 密集型进程优先级高于处理器密集型进程
C. 对资源要求少的进程优先级一般高于对资源要求多的进程
D. 优先级可以由用户自定义,但是只能是静态的

11.【参考答案】D
【解析】优先级分为静态优先级和动态优先级,用户可以自定义各个进程的静态优先级,也可以定义动态优先级的计算公式:例如高响应比优先调度算法,就是一种动态优先级调度算法,响应比计算公式可以由用户定义,故 D 选项错误。A、B、C 选项都是确定优先级时常用的原则。

12.一个好的 CPU 调度算法应当可以( )。
A. 降低系统吞吐率
B. 提高系统 CPU 利用率
C. 提高进程周转时间
D. 提高进程等待时间

12.【参考答案】B
【解析】好的 CPU 调度算法可以提高 CPU 的利用率,B 正确。CPU 利用率提高,相同时间会完成更多的任务,系统吞吐量增加,进程周转时间降低,等待时间降低,A、C、D 错误。

13.下列选项中,不应该提高进程优先级的场合是( )。
A. 进程发生 “饥饿” 现象
B. 用户需要一个进程在规定时间内完成
C. 进程等待的 I/O 操作完成,进入就绪队列
D. 进程时间片耗尽

13.【参考答案】D
【解析】进程发生饥饿时,应当增加其优先级,使其有机会使用处理器;当用户需要一个进程在规定时间完成时,也应该给予其高优先级以让该进程可以立即运行;I/O 操作完成后,可以适当提高进程优先级,A、B、C 均是提高优先级的场合。当时间片耗尽后,显然不应该提高其优先级,否则该进程可能再次使用处理器,导致其他进程无法得到处理器资源。一般来说,D 选项的情况下应该降低优先级。

14.某服务器系统中,一个低优先级进程被提交后等待了 6 年尚未被运行,这一现象在操作系统的 CPU 调度中被称为(?),(?)调度算法可以避免这一问题。以上问题的正确选项是( )。
I. 同步
II. 饥饿
III. 并行
IV. 死锁
I. 静态优先级
II. 最短剩余时间优先
III. 短进程优先
IV. 高响应比优先
A. I、IV
B. II、I
C. III、IV
D. II、IV

14.【参考答案】D
【解析】进程长时间得不到处理器资源被称为饥饿,高响应比优先调度算法考虑了进程的等待时间,故一个进程经过长时间的等待,优先级一定会变得很高,从而被分配处理器资源。

15.高响应比优先的进程调度算法综合考虑了进程的等待时间和计算时间,响应比的定义是( )。
A. 进程周转时间与等待时间之比
B. 进程周转时间与计算时间之比
C. 进程等待时间与计算时间之比
D. 进程计算时间与等待时间之比

15.【参考答案】B
【解析】响应比=1+S/T(S:等待时间;T:运行时间)。

16.某系统内存中,共有五个进程,该系统的就绪队列、阻塞队列中最多能同时存在的 PCB 数量分别是( )。
A. 5 个、5 个
B. 5 个、4 个
C. 4 个、5 个
D. 4 个、1 个

16.【参考答案】C
【解析】就绪队列中最多能有 4 个就绪进程,且另一个进程一定在运行态。阻塞队列中可以有 5 个进程。

17.下列调度算法中,有利于处理器密集型进程,不利于 I/O 密集型进程的是( )。
A. 先来先服务
B. 时间片轮转
C. 多级反馈队列
D. 优先级

17.【参考答案】A
【解析】先来先服务算法利于处理器密集型不利于 I/O 密集型,因为处理器密集型进程可以长时间占用处理器,I/O 密集型进程一旦进行 I/O 操作,就需要重新进入就绪队列排队,所以选择 A 选项。

18.下列关于调度算法的叙述中,错误的是( )。
A. 优先级调度算法偏向于用户的紧急作业
B. 短进程优先调度算法不利于长作业
C. 时间片轮转算法利于人机交互
D. 多级反馈队列调度算法偏向长作业

18.【参考答案】D
【解析】用户的紧急作业会被赋予更高的优先级,A 选项正确;短进程优先调度算法利于短进程,长进程则可能长时间得不到处理器,B 选项正确;时间片轮转算法利于人机交互,因为响应时间很短,C 选项正确。多级反馈队列调度算法可以很好的满足各种作业,D 选项错误。

19.现在有三个同时到达的作业J1​,J2​和J3​,它们的执行时间分别是T1​,T2​,T3​,且T1​<T2​<T3​。系统按单道方式运行且采用短作业优先调度算法,则平均周转时间是( )。
A. T1​+T2​+T3​
B. (T1​+T2​+T3​)/3
C. (T1​+2T2​+3T3​)/3
D. (3T1​+2T2​+T3​)/3

19.【参考答案】D
【解析】执行顺序是J1​−J2​−J3​。J1​的周转时间是T1​,J2​的周转时间是T1​+T2​,J3​的周转时间是T1​+T2​+T3​。平均周转时间计算得到 D 选项。

20.某单处理器单道操作系统中,使用优先级调度算法,有三个进程在 0 时刻到达,则平均周转时间为( )。

A. t1​+t2​+t3​
B. (t1​+t2​+t3​)/3
C. (3t1​+2t2​+t3​)/3
D. (t1​+2t2​+3t3​)/3

20.【参考答案】D
【解析】执行顺序是作业 3 - 作业 2 - 作业 1。作业 3 的响应时间是t3​,作业二的响应时间是t3​+t2​,作业三的响应时间是t3​+t2​+t1​。平均周转时间计算得到 D 选项。

21.时间片轮转调度算法中,时间片的大小会影响算法效率。当时间片过小时,算法效率( );当时间片过大时,该算法转换为( )调度算法。
A. 不变;先来先服务
B. 下降;优先级
C. 提高;高响应比优先
D. 其他

21.【参考答案】B、A
【解析】若时间片过小,则调度程序运行频率会很高,因此占用大量的处理器资源,导致效率下降。若时间片大到每一个进程都能在一个时间片内运行完毕,则会变成先来先服务调度算法。

22.下列各个调度算法中,能够较好满足各类进程的是( )。
A. 多级反馈队列调度算法
B. 短进程优先调度算法
C. 最短剩余时间优先调度算法
D. 先来先服务调度算法

22.【参考答案】A
【解析】B、C 调度算法对长进程不利,D 调度算法对 I/O 密集型进程不利,多级反馈队列调度算法可以较好地满足各类进程。

23.某单处理器单道操作系统中,0 时刻 5 个批处理作业同时到达。分别使用短作业优先调度算法和先来先服务调度算法(按 3 - 1 - 2 - 5 - 4 顺序调度)时,平均周转时间分别为( )。

A. 8.4、12.4
B. 8.4、12.6
C. 8.6、12.4
D. 8.6、12.6

23.【参考答案】B
【解析】使用短作业优先调度算法时,平均周转时间计算表达式为(5×1+4×2+3×4+2×5+1×7)/5=42/5=8.4。使用先来先服务调度算法时,平均周转时间计算表达式为(5×4+4×7+3×1+2×5+1×2)/5=63/5=12.6。

24.下列关于时间片轮转算法的叙述中,不正确的是( )。
A. 在时间片轮转算法中,系统将 CPU 的处理时间划分成一个个时间片
B. 就绪队列中的各个进程轮流在 CPU 上运行,每次运行一个时间片
C. 时间片结束时,运行进程自动让出 CPU 并进入阻塞队列
D. 如果时间片长度很小,则调度程序抢占 CPU 的次数频繁,增加了系统开销

24.【参考答案】C
【解析】时间片耗尽后,进程变为就绪态,进入就绪队列,C 选项错误。

25.多级反馈(Feed Back)进程调度算法不具备的特性是( )。
A. 资源利用率高
B. 响应速度快
C. 系统开销小
D. 并行度高

25.【参考答案】C
【解析】多级反馈队列中的各级队列可以使用不同的调度算法,从而较好地满足各个进程。C 选项不正确,因为多级反馈队列调度算法相较其他算法,实现上较为复杂,开销也会变大。

26.以下进程使用最短剩余时间调度算法进行调度,进程周转时间之和为( )。

A. 25
B. 26
C. 27
D. 28

26.【参考答案】C
【解析】注意此算法是可抢占算法,周转时间总和为4+1+8+12+2=27。
P1​:0 时刻到达。0 - 1 时刻运行,1 时刻被抢占,2 - 4 时刻运行,周转时间为 4。
P2​:1 时刻到达。1 - 2 时刻运行,周转时间为 1。
P3​:2 时刻到达。6 - 10 时刻运行,周转时间为 8。
P4​:3 时刻到达。10 - 15 时刻运行,周转时间为 12。
P5​:4 时刻到达。4 - 6 时刻运行,周转时间为 2。

27.设有 4 个作业同时到达,若采用最短作业优先调度算法,则作业的平均周转时间为( )。

A. 1.5h
B. 10.5h
C. 8.75h
D. 10.25h

27.【参考答案】C
【解析】执行顺序是作业 1 - 作业 4 - 作业 2 - 作业 3。不涉及抢占的调度算法较为简单,确定执行顺序后,每个进程的周转时间就等于运行时间 + 该进程之前的所有进程运行时间之和。平均周转时间为(4×2+3×3+2×5+1×8)/4=35/4=8.75。

28.在单道程序环境中,有 4 个作业 A、B、C、D,它们的提交时间与预计运行时间如下表。如果按短作业优先算法调度,它们的运行顺序为( )。

A. A - B - C - D
B. B - C - D - A
C. B - A - D - C
D. A - B - D - C

28.【参考答案】D
【解析】A 作业最先到达且就绪队列中无其他作业,故 A 作业先运行。当 A 作业运行结束后,B、C、D 均到达,再按照执行时间决定顺序为 B - D - C。

29.某单处理器单道操作系统中,使用多级反馈队列调度算法,队列 1、2、3 优先级递减,具体见下表。则这 4 个作业的周转时间之和为( )。

A. 25
B. 27
C. 28
D. 29

29.【参考答案】A
【解析】多级反馈队列调度算法涉及抢占和进程在各级队列间的移动。
周转时间之和为10+1+2+12=25。
J1​:0 时刻到达。0 - 2 时刻运行,2 时刻进入 2 级队列,7 - 10 时刻运行,周转时间为 10。
J2​:2 时刻到达。2 - 3 时刻运行,周转时间为 1。
J3​:3 时刻到达。3 - 5 时刻运行,周转时间为 2。
J4​:4 时刻到达。5 - 7 时刻运行,7 时刻进入 2 级队列;10 - 14 时刻运行,14 时刻进入 3 级队列;14 - 16 时刻运行。周转时间为 12。

30.一个动态优先级调度算法(优先数大的优先级低,优先级相同时选序号小的进行调度),根据等待时间和运行时间对优先数进行动态变化,算法如下:
① 处于就绪队列中的进程的优先数p根据等待时间t(单位秒)进行变化,p=p−t;
② 处于运行状态的进程的优先数p根据运行时间t(单位秒)进行变化,p=p+2×t;
③ 优先数p每隔 1 秒重新计算;
④ 采用抢占式调度策略。
根据下表给出的 5 个进程的到达时间和执行时间,回答下面的问题。(时间单位:秒)

(1) 画出 5 个进程执行的顺序图。
(2) 根据以上的调度算法,分别计算出每个进程的周转时间和响应时间。

2.2.10 真题演练

31.【2009】下列进程调度算法中,综合考虑进程等待时间和执行时间的是( )。
A. 时间片轮转调度算法
B. 短进程优先调度算法
C. 先来先服务调度算法
D. 高响应比优先调度算法

31.【参考答案】D
【解析】时间片轮转调度算法将处理机时间划分成固定长度的时间片,考虑了进程的执行时间而未考虑等待时间,A 不符合;短进程优先调度算法仅考虑了进程执行时间,B 不符合;先来先服务调度算法仅考虑了调度的公平性,C 不符合;高响应比调度算法通过等待时间和执行时间动态调整进程的优先级,D 符合。

32.【2010】下列选项中,降低进程优先级的合理时机是( )。
A. 进程的时间片用完
B. 进程刚完成 I/O,进入就绪队列
C. 进程长期处于就绪队列中
D. 进程从就绪态转为运行态

32.【参考答案】A
【解析】在进程的时间片用完后,进程由运行态变为就绪态,重新等待分配处理机,此时降低其优先级也可保证其他就绪进程使用处理机,A 选项正确;进程完成 I/O 后进入就绪队列等待使用处理机,应该提高其优先级,B 选项错误;进程长期处于就绪队列中说明一直未得到处理机使用权,应该提高其优先级以防止发生饥饿现象,C 选项错误;在实行抢占式调度算法的机器上,在进程刚从就绪态转化为运行态时,若降低优先级,可能会导致进程刚进入运行态就被抢占,降低了处理器效率,D 选项错误。
降低进程优先级的合理时机还有:在进程运行结束后应该降低该进程优先级,否则,刚运行结束的进程因为高优先级,会再次抢占处理器。

33.【2011】下列选项中,满足短任务优先且不会发生饥饿现象的调度算法是( )。
A. 先来先服务
B. 高响应比优先
C. 时间片轮转
D. 非抢占式短任务优先

33.【参考答案】B
【解析】A 和 C 没有考虑任务的长短,错误。D 考虑了任务的长短,但短进程优先有导致饥饿现象的风险,倘若就绪队列中一直有短任务进程进入,则长任务进程会一直等待。高响应比调度算法通过等待时间和执行时间动态调整进程的优先级:优先级等待时间要求服务时间要求服务时间。短任务计算优先级时因为分母更小,会比长任务优先,但长进程只要等待的时间足够长,一定会比短任务优先级高,故不会发生饥饿。

34.【2012】一个多道批处理系统中仅有P1​和P2​两个作业,P2​比P1​晚 5ms 到达,它们的计算和 I/O 操作顺序如下:
P1​:计算 60ms,I/O 80ms,计算 20ms
P2​:计算 120ms,I/O 40ms,计算 40ms
若不考虑调度和切换时间,则完成两个作业需要的时间最少是( )。
A. 240ms
B. 260ms
C. 340ms
D. 360ms

34.【参考答案】B
【解析】P1​先于P2​到达,则P1​先执行;因为是多道批处理系统,P2​到达后可以和P1​并发执行。使用甘特图分析,结果如下图所示。


 

35.【2013】某系统正在执行三个进程P1​、P2​和P3​,各进程的计算(CPU)时间和 I/O 时间比例如下表所示。为提高系统资源利用率,合理的进程优先级设置应为( )。

A. P1​>P2​>P3​
B. P3​>P2​>P1​
C. P2​>P1​=P3​
D. P1​>P2​=P3​

35.【参考答案】B
【解析】解题时需要思考如何提高系统资源利用率 — 尽可能保证处理器和 I/O 设备并行工作。
优先执行 I/O 时间占比高的进程P3​,在P3​阻塞时,其他进程可以占有处理器,从而实现系统资源的并发。如果考生感觉这样理解不直观,可以思考如果只存在P1​和P3​进程,优先级应该如何设置。显然,先执行P3​可以实现更高的系统资源利用率。优先级设计原则总结如表 2.14 所示。

优先级设计

                                                        设计原则

静态优先级

1. 系统进程高于用户进程
2. I/O 密集型高于处理器密集型
3. 资源要求低的进程高于资源要求高的进程
4. 用户自定义需求:如要求某任务准时完成,会设置高优先级

动态优先级

高响应比优先调度算法:等待时间越长,运行时间越短,优先级越高
多级反馈队列调度算法:进入就绪队列次数越多,优先级越低

36.【2014】下列调度算法中,不可能导致饥饿现象的是( )。
A. 时间片轮转
B. 静态优先级调度
C. 非抢占式短作业优先
D. 抢占式短作业优先

36.【参考答案】A
【解析】抢占式和非抢占式短作业优先调度算法中,若不断有短进程进入就绪队列,长进程就可能会发生饥饿现象。静态优先级调度中,如果不断有高优先级进程进入就绪队列,低优先级进程可能会发生饥饿。时间片轮转算法保证了各个进程公平使用处理机,不会发生饥饿。

37.【2016】某单 CPU 系统中有输入和输出设备各 1 台,现有 3 个并发执行的作业,每个作业的输入、计算和输出时间均分别为 2ms、3ms 和 4ms,且都按输入、计算和输出的顺序执行,则执行完 3 个作业需要的时间最少是( )。
A. 15ms
B. 17ms
C. 22ms
D. 27ms

37.【参考答案】B
【解析】利用甘特图解题,无论作业的执行顺序如何,都能在 17ms 执行完毕,如图 2.19 所示。

38.【2017】假设 4 个作业到达系统的时刻和运行时间如下表所示。系统在t=2时开始作业调度。若分别采用先来先服务和短作业优先调度算法,则选中的作业分别是( )。

A. J2​、J3​
B. J1​、J4​
C. J2​、J4​
D. J1​、J3

​38.【参考答案】D
【解析】根据题目可知,进行作业调度时,可以调度的作业有J1​、J2​、J3​。采用先来先服务算法时,会选取J1​,因为J1​最先到达;采用最短作业优先调度算法时,选取J3​,因为J3​的运行时间最短。

39.【2018】某系统采用基于优先权的非抢占式进程调度策略,完成一次进程调度和进程切换的系统时间开销为 1μs。在T时刻就绪队列中有 3 个进程P1​、P2​和P3​。其在就绪队列中的等待时间、需要的 CPU 时间和优先权见下表。若优先权值大的进程优先获得 CPU,从T时刻起系统开始进程调度,则系统的平均周转时间为( )。

A. 54μs
B. 73μs
C. 74μs
D. 75μs

39.【参考答案】D
【解析】①P2​的优先权最高,所以会先调度P2​,花费 1μs,切换成进程P2​;②2μs 到 25μs,执行进程P2​;③第 26μs,根据优先权,切换到进程P3​;④第 27μs 到 62μs,执行进程P3​;⑤第 63μs,切换到进程P1​;⑥第 64μs 到 75μs,执行进程P1​;
进程P1​的周转时间=30μs+75μs=105μs;进程P2​的周转时间=15μs+25μs=40μs;进程P3​的周转时间=18μs+62μs=80μs。系统的平均周转时间=(105μs+40μs+80μs)/3=75μs。

40.【2019】系统采用二级反馈队列调度算法进行进程调度。就绪队列Q1​采用时间片轮转调度算法,时间片为 10ms;就绪队列Q2​采用短进程优先调度算法;系统优先调度Q1​队列中的进程,当Q1​为空时系统才会调度Q2​中的进程;新创建的进程首先进入Q1​;Q1​中的进程执行一个时间片后,若未结束,则转入Q2​。若当前Q1​、Q2​为空,系统依次创建进程P1​、P2​后即开始进程调度。P1​、P2​需要的 CPU 时间分别为 30ms 和 20ms,则进程P1​、P2​在系统中的平均等待时间为( )。
A. 25ms
B. 20ms
C. 15ms
D. 10ms

40.【参考答案】C
【解析】系统依次创建进程P1​、P2​后,二者依次进入到队列Q1​,按照时间片轮转调度算法,两个进程先后被分配一个时间片 (10ms) 时间运行。根据二级反馈队列调度算法的性质,在各自的时间片用完后,两个进程先后进入Q2​队列。根据Q2​队列采用的短进程优先调度算法,此时需要考虑两个进程的剩余执行时间 (P1​剩余 20ms,P2​剩余 10ms) 并选择P2​进行调度。P2​运行结束后,调度P1​。具体时间节点为:①1ms 到 10ms 执行P1​;②11ms 到 20ms 执行P2​;③21ms 到 30ms 执行P2​;④31ms 到 50ms 执行P1​。P1​等待时间为 20ms (11ms 到 30ms);P2​等待时间为 10ms (1ms 到 10ms)。平均等待时间为(20ms+10ms)/2=15ms,故选 C。

41.【2020】下列与进程调度有关的因素中,在设计多级反馈队列调度算法时需要考虑的是( )。
I. 就绪队列的数量
II. 就绪队列的优先级
III. 各就绪队列的调度算法
IV. 进程在就绪队列间的迁移条件
A. 仅 I、II
B. 仅 III、IV
C. 仅 II、III、IV
D. I、II、III、IV

41.【参考答案】D
【解析】本题实际在考查多级反馈队列调度算法的特点。首先该调度算法需要定义多个就绪队列,所以 I 需要考虑;第二,当多个就绪队列均有进程排队时,需要确定先调度哪个队列的进程,也就是确定各个队列优先级,所以 II 需要考虑;第三,各个就绪队列的调度算法可以是不同的,所以要为每个就绪队列确定一个调度算法,III 需要考虑;第四,多级反馈队列调度算法需要一个进程可以在不同队列间迁移,这能体现出 “反馈” 这一特点,如果不迁移就成了多级队列调度算法,所以 IV 需要考虑。

42.【2021】下列内核的数据结构程序中,分时系统实现时间片轮转调度需要使用的是( )。
I. 进程控制块
II. 时钟中断处理程序
III. 进程就绪队列
IV. 进程阻塞队列
A. 仅 II、III
B. 仅 I、IV
C. 仅 I、II、III
D. 仅 I、II、IV

42.【参考答案】C
【解析】进程控制块是描述进程状态和特性的数据结构,记录了进程占用 CPU 的时间,所以 I 需要使用;使用时间片轮转调度算法时,在每次时钟中断时,时钟中断处理程序会判断当前运行进程时间片是否耗尽,如果耗尽会进行进程调度,所以 II 需要;当一个进程的时间片耗尽且仍未完成,则该进程进入进程就绪队列,所以 III 需要;时间片轮转调度算法不涉及阻塞状态,所以 IV 不需要,正确答案选 C。

43.【2021】下列事件中,可引起进程调度程序执行的是( )。
I. 中断处理结束
II. 进程阻塞
III. 进程执行结束
IV. 进程的时间片用完
A. 仅 I、III
B. 仅 II、IV
C. 仅 III、IV
D. I、II、III、IV

43.【参考答案】D
【解析】I 正确,例如时钟中断发生时,若当前进程时间片用尽,则会发生进程调度;II 正确,例如此刻运行的进程进行了 I/O 操作,在数据到来之前,该进程会主动阻塞,操作系统会进行进程调度;III 正确,当一个进程运行结束后,需要调度其他进程占有处理器运行,如果没有其他就绪进程,则会调度闲逛进程;IV 正确,是进程调度的时机之一;所以正确答案是 D。

44.【2016】某进程调度程序采用基于优先数(priority)的调度策略,即选择优先数最小的进程运行,进程创建时由用户指定一个 nice 作为静态优先数。为了动态调整优先数,引入运行时间 cpuTime 和等待时间 waitTime,初值均为 0。进程处于执行态时,cpuTime 定时加 1,且 waitTime 置 0;进程处于就绪态时,cpuTime 置 0,waitTime 定时加 1。请回答下列问题。
(1) 若调度程序只将 nice 的值作为进程的优先数,即 priority = nice,则可能会出现饥饿现象,为什么?
(2) 使用 nice、cpuTime 和 waitTime 设计一种动态优先数计算方法,以避免产生饥饿现象,并说明 waitTime 的作用。

44.【参考答案】
(1) 根据第一问的描述,如果调度程序只将 nice 值作为进程的优先数,则本调度算法为静态优先级调度算法。如果有进程的优先级过低,而就绪队列中不断有高优先级进程进入,则该低优先级进程会一直无法使用处理机,从而发生饥饿现象。
(2) 解决饥饿现象的手段之一,就是引入动态优先数,通过动态调整进程的优先数来使得每个进程都可以在有限时间内使用处理机。当设计动态优先数时,不难想到可以类比高响应比优先调度算法,保证设计出来的动态优先数有三个特点:两个进程如果其他指标均相同,由 nice 决定优先数;低优先数进程通过长时间等待优先数会减小;进程使用处理机运行后优先数会变大。最终设计出的计算公式为:
                                        priority=(β×cpuTime)÷(1+nice+α×waitTime)
其中,常数β>0,常数α>0。公式中的除数需要加 1,从而避免除数为 0。α和β用于调整waitTime和cpuTime的影响程度。waitTime用来提高那些长时间等待处理器资源的进程的优先级,防止其饥饿。

相关文章:

  • RENAME 语句与RENAME选项学习
  • TCP Socket编程
  • C语言_函数hook_LD_PRELOAD原理和示例
  • opencv处理图像(二)
  • 进阶二:基于HC-SR04和LCD1602的超声波测距
  • 【ts】for in对象时,ts如何正确获取对应的属性值
  • sched_fair 调度:负载权重、虚拟运行时间与最小虚拟时间
  • Js 判断浏览器cookie 是否启用
  • 2025盘古石初赛WP
  • linux 开发小技巧之git增加指令别名
  • 路由策略和策略路由的区别以及配置案例
  • 用Python绘制动态彩色ASCII爱心:技术深度与创意结合
  • FHE与后量子密码学
  • 解决使用宝塔Linux部署前后端分离项目遇到的问题
  • Nakama:让游戏与应用更具互动性和即时性
  • 相机Camera日志分析之八:高通Camx HAL架构opencamera三级日志详解及关键字
  • spring中的@Inject注解详情
  • linux perf top分析系统性能
  • 深入解析JavaScript变量作用域:var、let、const全攻略
  • [架构之美]从零开始整合Spring Boot与Maven(十五)
  • 重庆荣昌出圈背后:把网络流量变成经济发展的增量
  • 玉渊谭天丨中方为何此时同意与美方接触?出于这三个考虑
  • 央行:当前我国债券市场定价效率、机构债券投资交易和风险管理能力仍有待提升
  • 胳膊一抬就疼,炒菜都成问题?警惕这种“炎症”找上门
  • 九家企业与上海静安集中签约,投资额超10亿元
  • “80后”计算机专家唐金辉已任南京林业大学副校长