第二章 进程管理 自测习题

一、单项选择题

1 .在操作系统中引入“进程”概念的主要目的是(  C  )。

 A. 改善用户编程环境

 B. 提高程序的运行速度

 C. 描述程序动态执行过程的性质

 D. 使程序与计算过程一一对应

解析:
引入进程概念的根本目的是为了在多道程序环境下,能够描述和记录程序在并发执行时的动态变化过程(如状态、资源占用、CPU现场等)。程序本身是静态的,而进程是动态的。

A 改善用户编程环境(不是主要目的,那是操作系统接口或高级语言的事)

B 提高程序的运行速度(进程引入会带来切换开销,不直接提速)

D 使程序与计算过程一一对应(错,一个程序可对应多个进程,如多次执行同一个程序)

2 .进程与程序之间有密切联系,但又是不同的概念。二者的一个本质区别是(  A  )。

 A. 程序是静态概念,进程是动态概念

 B. 程序是动态概念,进程是静态概念

 C. 程序保存在文件中,进程存放在内存中

 D. 程序顺序执行,进程并发执行

3 .在操作系统中,进程的最基本的特征是(  A  )。

 A. 动态性和并发性

 B. 顺序性和可再现性

 C. 与程序的对应性

 D. 执行过程的封闭性

4 .为了描述进程的动态变化过程,采用了一个与进程相联系的(  C  ),根据它而感知进程的存在。

 A. 进程状态字

 B. 进程优先数

 C. 进程控制块

 D. 进程起始地址

解析:
进程控制块(PCB)是操作系统为了描述和管理进程而专门设置的数据结构,它记录了进程的状态、寄存器、优先级、资源占用等信息。PCB是进程存在的唯一标志,操作系统通过PCB来感知、控制和调度进程。

A 进程状态字(是PCB中的一个字段,不是感知进程存在的整体依据)

B 进程优先数(也是PCB中的一个调度相关字段)

D 进程起始地址(是内存管理相关信息,也属于PCB的一部分)

5 .进程控制块是描述进程状态和特性的数据结构,一个进程( D   )。

 A. 可以有多个进程控制块

 B. 可以和其他进程共用一个进程控制块

 C. 可以没有进程控制块

 D. 只能有唯一的进程控制块

6 .在单处理机系统中,处于运行状态的进程(  A  )。

 A. 只有一个

 B. 可以有多个

 C. 不能被挂起

 D. 必须在执行完后才能被撤下

7 .已经获得除(  C  )以外的所有运行所需资源的进程处于就绪状态。

 A. 存储器

 B. 打印机

 C. CPU

 D. 磁盘空间

8 .进程从运行状态变为阻塞状态的原因是(  A  )。

 A. 输入或输出事件发生

 B. 时间片到

 C. 输入或输出事件完成

 D. 某个进程被唤醒

9 .某进程由于需要从磁盘上读入数据而处于阻塞状态。当系统完成了所需的读盘操作后,此时该进程的状态将(  D  )。

 A. 从就绪变为运行

 B. 从运行变为就

 C. 从运行变为阻塞

 D. 从阻塞变为就绪

1 0.下列进程状态的转换中,不正确的是( A   )。

 A. 从就绪到阻塞

 B. 从运行到就绪

 C. 从就绪到运行

 D. 从阻塞到就绪

1 1.一个进程被唤醒意味着(  B  )。

 A. 该进程重新占有了CPU

 B. 进程状态变为就绪

 C. 它的优先权变为最大

 D. 其PCB移至就绪队列的队首

解析:
唤醒通常指进程因等待的事件发生(如I/O完成、信号量被V操作)而从阻塞态被移出,状态变为就绪态,并放入就绪队列中等待调度。

A 该进程重新占有了CPU(不一定,它只是进入就绪队列,何时获得CPU由调度决定)

C 它的优先权变为最大(唤醒不会自动改变优先级,除非调度策略特殊设计)

D PCB移至就绪队列的队首(不一定,一般放入队尾或按某种算法插入,不一定是队首)

因此,唤醒的核心含义是状态从阻塞变为就绪

1 2.现代操作系统中引入线程以后,进程(   )。

 A. 只是资源分配的单位

 B. 只是调度运行的单位

 C. 既是资源分配的单位,又是调度运行的单位

 D. 失去作用

解析:
引入线程之后,进程依然是资源分配(如内存、文件、I/O设备)的基本单位,而调度和运行的基本单位变成了线程。进程不再直接参与CPU调度,线程共享进程的资源但独立被调度。

B 只是调度运行的单位(错误,这是线程的角色)

C 既是资源分配的单位,又是调度运行的单位(这是未引入线程前的进程角色)

D 失去作用(错误,进程依然是资源管理和保护的重要单位)

因此,现代操作系统中,进程是资源分配单位,线程是调度运行单位。

1 3.下列关于进程和线程的叙述中,正确的是( C  )。

 A. 一个进程只可拥有一个线程

 B. 资源分配给线程,处理机分配给进程

 C. 一个进程可拥有若干个线程

 D. 一个线程可在若干个进程地址空间活动

1 4.下列关于引入线程的好处的描述中,不正确的是( C  )。

 A. 并发性高,提高效率 

 B. 易于调度,代价低

 C. 利于分配资源

 D. 充分发挥多处理器的功能

解析:
线程的优点主要是提高并发性、降低调度开销、便于在多核处理器上并行。但资源分配仍然是进程的职责,线程共享所属进程的资源,本身并不独立分配资源。

A 并发性高,提高效率(正确,线程切换比进程快,可提高系统吞吐量)

B 易于调度,代价低(正确,线程上下文切换比进程轻量)

C 利于分配资源(错误,资源分配仍以进程为单位,线程不独立拥有资源)

D 充分发挥多处理器的功能(正确,同一进程的多个线程可并行运行在不同CPU核上)

1 5.两个进程合作完成一个任务,在并发执行中,一个进程要等待其合作伙伴发来信息,或者建立某个条件后再向前执行,这种关系是进程间的(   )关系。

 A. 同步    

 B. 互斥

 C. 竞争

 D. 合作

解析:
题目描述的是一个进程需要等待另一个进程发送信息或满足某个条件后才能继续执行,这种有先后顺序、相互协作的关系就是进程间的同步关系。

A 同步(正确,涉及进程间按特定顺序推进或传递条件)

B 互斥(错误,互斥是指多个进程不能同时进入临界区,这里不强调资源竞争)

C 竞争(错误,竞争是多个进程争抢资源,题中是协作等待)

D 合作(虽然字面上含义接近,但操作系统术语中这种合作中的等待条件特指同步)

1 6.以下不属于进程高级通信方式的是(  B  )。

 A. 共享内存方式

 B. 进程互斥和同步方式

 C. 消息传递方式

 D. 管道文件方式

1 7.在进程通信中,使用信箱方式交换信息的是( B   )。

 A. 低级进程通信

 B. 消息传递方式

 C. 共享内存方式

 D. 管道文件方式

1 8.在一段时间内,只允许一个进程访问的资源称为(  C  )。

 A. 共享资源 

 B. 临界区

 C. 临界资源

 D. 共享区

1 9.如果信号量S的值是0 , 此时进程A执行P(S)操作,那么,进程A会( B )。

 A. 继续运行

 B. 进入阻塞态,让出CPU

 C. 进入就绪态,让出CPU

 D. 继续运行,并唤醒S队列头上的等待进程

2 0.若P、V操作的信号量S初值为2,当前值为 -1,则表示有(  B  )个等待进程。

 A. 0

 B. 1

 C. 2

 D. 3

解析:
信号量 S 的初值为 2,当前值为 -1
PV 操作中,信号量的值表示可用资源的数量:

S ≥ 0 时,S 的值表示当前可用的资源数量;

S < 0 时,其绝对值表示等待该资源的进程个数。

这里 S = -1| -1 | = 1,所以有 1 个等待进程

2 1.在执行V操作时,当信号量的值(   ),应释放一个等待该信号量的进程。

 A. 小于0

 B. 大于0

 C. 小于等于0

 D. 大于等于0

解析:
V 操作执行 S = S + 1,如果加 1 之后 S ≤ 0,说明在 V 操作之前 S ≤ -1,即等待队列中至少有一个进程被阻塞,这时需要从该信号量的等待队列中唤醒一个进程,使其变为就绪态。

A 小于0(不完整:当 S 原本为 -1V S=0,也满足等于0的情况,此时仍需唤醒)

B 大于0(错误,此时没有等待进程)

C 小于等于0(正确,包含等于0的情况,即 V S=-1

D 大于等于0(错误,大于0时不需要唤醒)

2 2.信号量S的初值为8,在S上执行了10次P操作,6次V操作后,S的值为(  D  )。

 A. 10

 B.

 C. 6

 D. 4

解析:

信号量 S 初值 = 8

每执行一次 P 操作,S 1

每执行一次 V 操作,S 1

执行 10 P 操作:8 - 10 = -2
执行 6 V 操作:-2 + 6 = 4

因此,最终 S 的值为 4

2 3.有9个生产者,6个消费者,共享容量为8的缓冲区。在这个生产者-消费者问题中,互斥使用缓冲区的信号量mutex的初值应该为(  A  )。

 A. 1

 B. 6

 C. 8

 D. 9

解析:
在生产者-消费者问题中,mutex 是用于实现对缓冲区(缓冲池)互斥访问的信号量。无论有多少个生产者或消费者,共享缓冲区作为临界资源,同一时刻只能允许一个进程(生产者或消费者)去操作缓冲区(如修改指针、存取数据)。

因此 mutex 的初值应为 1,这是标准的互斥信号量设定。

2 4.两个进程争夺同一个资源( B   )。

 A. 一定死锁

 B. 不一定死锁

 C. 不会死锁 

 D. 以上说法都不对

2 5.系统出现死锁的原因是(  C  )。

 A. 计算机系统发生了重大故障

 B. 有多个封锁的进程同时存在

 C. 若干进程因竞争资源而无休止地循环等待着,而且都不释放已占有的资源

 D. 资源数大大少于进程数,或进程同时申请的资源数大大超过资源总数

2 6.死锁的四个必要条件中,无法破坏的是(   )。

 A. 互斥条件

 B. 不可抢占条件

 C. 占有且申请条件

 D. 循环等待条件

解析:
死锁的四个必要条件为:

1.互斥条件

2.请求与保持条件(占有且申请)

3.不可抢占条件

4.循环等待条件

其中,互斥条件是指资源一次只能被一个进程使用。对于某些资源(如打印机、磁带机等),其物理特性决定了它们天然无法被多个进程同时共享,因此互斥条件通常无法破坏。而其他三个条件可以通过资源分配策略、剥夺调度、资源有序申请等方法加以破坏。

A 互斥条件(正确,有些资源必须互斥访问,无法改变)

B 不可抢占条件(可以破坏,如允许强制剥夺资源)

C 占有且申请条件(可以破坏,如要求进程一次性申请所有资源)

D 循环等待条件(可以破坏,如给资源编号,按序申请)

二、判断题

1 .简单地说,进程是程序的执行过程。因而,进程和程序是一一对应的。( B   )

 A.

 B.

2 .程序在运行时需要很多系统资源,如内存、文件、设备等,因此操作系统以程序为单位分配系统资源。(  B  ) 

 A.

 B.

3 .进程执行的相对速度不能由进程自己来控制。(  A  )

 A.

 B.

4 .进程控制块(PCB)是专为用户进程设置的私有数据结构,每个进程仅有一个PCB。( B )  

 A.

 B.

5 .进程控制块(PCB)是进程存在的唯一标志。( A  )

 A.

 B.

6 .在进程状态的转换中,从就绪态转换到阻塞态是不可能实现的。(  A  )

 A.

 B.

7 .进程从运行状态变为阻塞状态的原因是输入或输出事件发生。( A   )

 A.

 B.

8 .进程从运行状态变为阻塞状态的原因是时间片到时。(  B  )

 A.

 B.

9 .一个进程被唤醒意味着该进程重新占有了CPU。(  

 A.

 B.

1 0.如同人类的族系一样,操作系统中众多的进程也存在族系关系,并构成一棵树形的进程族系图。(  A  )

 A.

 B.

1 1.进程之间的互斥,主要源于进程之间的资源竞争,从而实现多个相关进程在执行次序上的协调。(B

 A.

 B.

解析:
进程之间的互斥确实源于资源竞争,目的是保证多个进程不能同时进入临界区(共享资源)。但题目后半句说从而实现多个相关进程在执行次序上的协调”——这是同步的作用,而不是互斥。互斥解决的是同时访问冲突,同步才解决执行次序协调

1 2.进程A和进程B都要使用系统中同一台打印机,为了保证打印结果的正确性,两个进程要先后分别使用打印机,这属于进程的同步关系。( B  )

 A.

 B.

1 3.进程的互斥和同步机构交换的信息量大,被归结为高级通信。(B

 A.

 B.

1 4.管道文件方式属于进程的高级通信。(A  )

 A.

 B.

1 5.信号量机制是一种有效地实现进程同步与互斥的工具。信号量只能由PV操作来改变。(A

 A.

 B.

1 6.V操作是对信号量执行加1操作,意味着释放一个单位资源,如果加1后信号量的值小于等于零,则从等待队列中唤醒一个进程,现进程变为阻塞状态,否则现进程继续进行。(   B  )

 A.

 B.

1 7.系统产生死锁的根本原因是资源有限且操作不当。因此,当系统提供的资源少于并发进程的需求时,系统就产生死锁。(  B  )

 A.

 B.

1 8.解决死锁的方法有死锁的预防、死锁的避免、死锁的检测与恢复。( A

 A.

 B.

1 9.在Linux系统中,用户进程既可以在用户模式下运行,也可以在内核模式下运行。( A

 A.

 B.

解析:
Linux 系统中,用户进程通常运行在用户模式(用户态),但当它通过系统调用、中断或异常进入内核空间时,会切换到内核模式(内核态)以执行特权操作(如文件读写、内存管理、设备访问)。因此,用户进程确实可以在两种模式下运行(通过模式切换)。

三、简答题

1 、在操作系统中为什么要引入进程概念?它与程序的区别和联系是什么?

在操作系统中引入进程概念,主要是为了实现多道程序环境下的程序并发执行。早期的单道程序系统中,程序顺序执行,CPUI/O设备速度不匹配导致资源浪费;引入多道程序技术后,多个程序需要交替使用CPU和资源,但静态的程序无法描述程序执行过程中的动态变化(如执行进度、资源占用状态、寄存器内容等),也无法支持系统对资源的分配、调度与保护。因此,操作系统引入了进程这一概念,用来描述程序的一次动态执行过程,并作为系统分配资源、调度CPU以及进行并发控制的基本单位。

进程与程序的区别主要体现在:程序是静态的、永久的,是存储在磁盘上的指令与数据的集合;而进程是动态的、暂时的,是程序在内存中的一次执行过程,具有创建、运行、等待、结束等生命周期。从组成来看,程序仅包含代码和数据;而进程除了程序代码和数据外,还包括进程控制块(存放状态、寄存器、优先级等信息)以及系统为它分配的资源。一个程序可以被多次执行,从而对应多个不同的进程;反之,一个进程也可以在执行过程中调用其他程序。

进程与程序的联系是:进程是程序的一次执行实例,程序是进程赖以运行的静态文本。没有程序,进程就失去了执行的内容;没有进程,程序仅仅是一份存储在磁盘上的文件,无法发挥任何计算作用。可以说,程序是剧本,而进程是演出。操作系统通过进程管理机制,使同一份程序可以并发地生成多个独立的进程,从而实现对CPU与资源的高效利用。

2 、进程的基本状态有哪几种?

进程的基本状态通常分为以下三种:

1 .就绪状态:进程已获得除CPU以外的所有必要资源(如内存、I/O设备),只要获得CPU时间片就可以立即运行。通常系统中多个进程处于就绪态,排成一个就绪队列。

2 .运行状态:进程已获得CPU,其指令正在被CPU执行。在单核系统中,任何时刻最多只有一个进程处于运行态;多核系统中可能有多个。

3 .阻塞状态(或称等待状态、睡眠状态):进程因等待某一事件的发生(如等待I/O操作完成、等待某个信号量或键盘输入)而暂时无法继续执行。此时即使把CPU分配给该进程,它也无法执行。进程在阻塞态时通常主动释放CPU,并进入相应的等待队列。

3 、 PCB的作用是什么?它是怎样描述进程的动态性质的?

PCB(进程控制块)是操作系统中用于描述和管理进程的一个专门数据结构,它的核心作用是:使一个在多道程序环境下不能独立运行的程序(静态实体),成为一个能够独立运行、并发执行的进程(动态实体)。可以说,PCB是进程存在的唯一标志——操作系统通过PCB来感知、控制和管理每一个进程。

具体而言,PCB的作用体现在以下几个方面:

1 .作为进程的标识PCB中存放了进程的唯一标识符(如进程ID),用于区分不同的进程。

2 .存储进程的状态信息:记录进程当前处于就绪、运行还是阻塞等状态,供调度程序决策。

3 .保存CPU现场信息:当进程被切换出CPU时,其寄存器内容、程序计数器、堆栈指针等现场数据会被保存在PCB中;当进程再次获得CPU时,再从PCB中恢复现场,使进程能继续执行。这正是描述进程动态性的关键。

4 .管理资源分配PCB中记录了进程占用的内存区域、打开的文件、I/O设备等资源信息,便于系统进行分配和回收。

5 .支持进程调度与同步通信PCB中包含进程优先级、调度队列指针等信息,用于实现调度算法;同时也提供信号量、消息队列指针等用于进程间通信与同步。

PCB是怎样描述进程的动态性质的?

进程的动态性质体现在它并非静止不变,而是在生命周期中不断变化状态、占用和释放资源、被切换进或切换出CPUPCB通过以下方式刻画这种动态过程:

状态字段PCB中的进程状态字段会随进程的执行不断改变(如从就绪运行阻塞就绪),记录了进程在某一时刻的动态行为。

现场保护机制:每次进程切换时,PCB暂存CPU现场;下次恢复时再从PCB加载。这一保存-恢复过程直接反映了进程在CPU上断续推进的动态特性。

资源清单的动态变化PCB中的资源列表不是固定的,随着进程申请和释放资源,这些信息会实时更新,体现了进程运行过程中对资源的动态占用。

队列指针:进程因状态变化会在就绪队列、阻塞队列等之间移动,PCB中的链接指针记录了这个流动过程,使操作系统能够动态调度进程。

简单总结:程序是静止的,而PCB通过不断更新其内部的状态、现场、资源等字段,配合调度机制,完整地记录和驱动了进程从创建到消亡的全过程动态轨迹。 没有PCB,操作系统就无法描述、控制和感知进程的动态行为。

4 、PCB表的组织方式主要有哪几种?分别简要说明。

PCB(进程控制块)表的组织方式主要有以下三种:

1 .线性方式(线性表):将系统中所有进程的PCB集中存放在一个连续的内存区中,通过数组或线性链表进行管理。这种方式实现简单、访问速度快(可通过下标直接定位),但查找特定PCB时需要扫描整个表,效率较低;同时系统最大进程数受限于数组长度,不便于动态增减,适用于进程数较少的系统。

2 .链接方式(链表):将同一状态(如就绪态、阻塞态)或同一类别的进程PCB通过指针链接成多个队列(如就绪队列、多个阻塞队列等)。每个PCB中包含指向下一个PCB的指针,系统只需分别维护每个队列的头指针。这种方式便于进程状态的切换——当进程状态改变时,只需从原队列中取出并插入新队列即可,增删操作效率高,且进程数量不受表大小硬性限制。这是目前最常用的组织方式。

3 .索引方式(索引表):系统为不同状态的进程分别建立索引表,每个索引表的一个表项指向一个PCB。系统先通过索引表定位到具体PCB,再对其进行操作。这种方式融合了线性方式的连续存储与链接方式的多队列思想,提高了查询特定状态进程的效率,但需要额外的索引表存储空间。通常用于支持更复杂的进程管理和调度策略。

5 、进程进入临界区的调度原则是什么?

进程进入临界区的调度原则,主要是为了保证多个并发进程在访问共享资源(临界资源)时的正确性与安全性。这些原则通常被称为同步机制应遵循的四大准则,具体如下:

1 .空闲则入:当没有进程处于临界区时,任何有权进入的进程都可以立即进入自己的临界区。这意味着临界区资源处于空闲状态时,不能阻止进程进入。

2 .忙则等待:当已有进程进入自己的临界区时(即临界区正被占用),其他试图进入临界区的进程必须等待,不能强行进入。这保证了每次最多只有一个进程在临界区内执行,从而避免数据不一致。

3 .有限等待:对于要求进入临界区的进程,应保证它在有限的时间内能够进入,不能出现死等饥饿现象。也就是说,操作系统或同步机制要避免某个进程被无限期地拒绝进入临界区。

4 .让权等待:当进程无法进入临界区(即被阻塞)时,它应当立即释放CPU(让出处理机),而不能在CPU忙等待(即不停地循环测试锁状态)。这样做是为了提高CPU利用率,避免空转浪费。不过需要指出的是,在实际实现中,像自旋锁这类机制会违反让权等待,但它在多核系统中仍有特定用途;而经典的同步原语(如信号量、管程)通常会设计为让权等待。

6 、简述信号量的定义和作用。PV操作原语是如何定义的?

信号量是一个用于进程间同步与互斥的整型变量,其定义通常包含一个整数值和一个等待队列指针。信号量的值表示可用资源的数量或等待进程的标志:当值大于0时,表示当前可用资源的个数;当值等于0时,表示没有可用资源;当值小于0时,其绝对值表示等待使用该资源的进程个数。

信号量的主要作用是实现进程的互斥与同步。在互斥场景中,信号量用于保护临界资源,确保同一时刻只有一个进程进入临界区;在同步场景中,信号量用于协调进程之间的执行顺序,例如一个进程需等待另一个进程完成某个操作后才能继续执行。

PV操作原语的定义如下:

P操作(意为测试:执行时,将信号量S的值减1(即s=s-1)。如果减1s>=0,则该进程继续执行;如果减1s<0,则该进程被阻塞,并放入与S相关的等待队列中,同时让出CPU

V操作(意为增加:执行时,将信号量S的值加1(即s=s+1)。如果加1s>0,则该进程继续执行;如果加1s<=0,则表示等待队列中有被阻塞的进程,此时从S的等待队列中唤醒一个进程,使其进入就绪状态,而当前进程继续执行(或根据调度算法决定是否立即切换)。

PV操作是原子操作(即不可中断的原语),在执行过程中不会被系统调度打断,从而保证了信号量值修改的可靠性。通过合理设置信号量的初始值并搭配PV操作,可以有效解决经典的进程同步与互斥问题

7 、计算机系统中产生死锁的根本原因是什么?

计算机系统中产生死锁的根本原因可以归结为以下两点:

1 .资源竞争:当多个进程共享系统中的有限资源(如CPU、内存、I/O设备、文件等)时,如果每个进程都占用了部分资源,同时又继续请求其他已被其他进程占用的资源,就可能导致所有进程都无法继续执行,从而形成死锁。资源竞争是产生死锁的物质基础,尤其是那些不可抢占资源(如打印机、磁带机)和可消耗资源(如缓冲区消息)更容易引发死锁。

2 .进程推进顺序不当:即使系统中资源充足,如果进程并发执行时的顺序不合理,也可能导致死锁。例如,进程A等待进程B占用的资源,而进程B又在等待进程A占用的资源,这种循环等待的推进顺序就会使各进程相互阻塞,无法推进。

8 、发生死锁的四个必要条件是什么?

死锁的发生需要同时满足四个必要条件如下

互斥条件:资源一次只能被一个进程使用。

请求与保持条件:进程已保持至少一个资源,同时又请求新的资源,但该资源已被其他进程占用。

不可抢占条件:进程已获得的资源在未使用完之前不能被系统强制剥夺。

循环等待条件:存在一组进程 {P0, P1, …, Pn},其中 P0 等待 P1 占用的资源,P1 等待 P2 占用的资源,……Pn 等待 P0 占用的资源。

9 、一般解决死锁的方法有哪三种?

一般解决死锁的方法可以归纳为以下三种:

1 .死锁预防:通过破坏死锁产生的四个必要条件(互斥、请求与保持、不可抢占、循环等待)中的至少一个来防止死锁发生。例如:破坏请求与保持条件可采用静态资源分配法(进程一次性申请所有资源);破坏不可抢占条件允许系统强行剥夺进程已占有的资源;破坏循环等待条件可对资源按序编号并要求进程按递增顺序申请资源。这种方法实现简单,但可能导致资源利用率低或进程执行效率下降。

2 .死锁避免:在系统运行过程中,每次进程申请资源时都通过某种算法(最著名的是银行家算法)动态判断本次分配是否会导致系统进入不安全状态。如果分配后系统仍处于安全状态(存在一种资源分配序列使所有进程都能完成),则允许分配;否则让进程等待。死锁避免不需要像预防那样强行限制资源申请方式,但需要进程预先声明最大资源需求,且算法开销较大。

3 .死锁检测与恢复:系统允许死锁发生,但会定期调用检测算法(如通过资源分配图判断是否存在循环等待)来检查是否已出现死锁。一旦检测到死锁,则采取恢复措施:常用的恢复方法包括撤销一个或多个死锁进程(直至打破循环等待)、从死锁进程中强制抢占资源分配给其他进程、或者回滚进程到某个安全检查点。这种方法对资源申请方式无约束,但死锁检测本身会消耗系统开销,且恢复过程可能导致数据不一致或进程执行中断。

1 0、是否所有的共享资源都是临界资源?为什么?

不是,所有的共享资源并不都是临界资源。原因如下:

共享资源是指系统中可以被多个进程共同访问的资源,例如内存中的共享数据、磁盘文件、打印机等。而临界资源是共享资源的一个子集,特指那些一次仅允许一个进程访问(即必须互斥使用)的共享资源。如果一个共享资源允许多个进程同时访问而不会导致数据不一致或逻辑错误,那么它就不是临界资源。

具体来说,共享资源可以分为两类:

1 .可共享资源(非临界资源):允许多个进程同时访问,且并发访问不会产生副作用或错误。例如,只读的数据文件(多个进程同时读取不会破坏数据)、磁盘本身(通过文件系统调度可以并发读写不同区域)、内存中的只读代码段等。这类资源不需要互斥访问,因此不属于临界资源。

2 .不可共享资源(临界资源):一次只能由一个进程使用,必须互斥访问。例如,打印机(同时打印多个任务会产生乱码)、共享变量(如多个进程同时修改同一个计数器会导致结果错误)、链表等共享数据结构(并发插入/删除节点会破坏结构完整性)。这些资源的并发访问必须通过互斥机制(如信号量、锁)来保护,否则会产生不可预知的结果。

四、应用题

1 、用如图所示的进程状态转换图能够说明有关处理机管理的大量内容。

https://lms.ouchn.cn/api/uploads/1599584/in-rich-content?created_at=1647446743

图  进程状态转换图

试回答:

① 什么事件引起每次显著的状态变迁?

② 下述状态变迁因果关系能否发生?为什么?

答:① 引起每次显著状态变迁的事件:

经典三态模型中的状态变迁及引起事件如下:

就绪运行:进程调度程序选中该进程(例如时间片轮转、优先级调度),将CPU分配给它。

运行就绪:发生中断事件,常见原因有:时间片用完、被高优先级进程抢占(抢占式调度)。

运行阻塞:进程请求某资源或等待某事件发生,且暂时无法得到满足,例如:请求I/O(如读磁盘)、等待信号量、等待子进程结束、等待系统调用结果。

阻塞就绪:进程所等待的事件已完成,例如:I/O操作结束、信号量被释放、所等待的资源变为可用。

下述状态变迁因果关系能否发生?为什么?

阻塞运行:不能直接发生。因为阻塞态进程缺乏继续执行的必要资源(如等待的I/O未完成),即使强行分配CPU也无法运行,必须先经过阻塞就绪事件。

就绪阻塞:不能直接发生。进程必须处于运行态才有机会执行导致阻塞的操作(如请求I/O),处于就绪态时尚未获得CPU,无法执行任何请求资源的指令。

2 、系统中只有一台打印机,有三个用户的程序在执行过程中都要使用打印机输出计算结果。设每个用户程序对应一个进程。问:这三个进程间有什么样的制约关系?试用PV操作写出这些进程使用打印机的算法。

答:这三个进程之间存在着互斥的制约关系。因为系统中只有一台打印机,而多个进程都需要使用它,且打印机不允许同时被多个进程使用(否则输出会混杂)。因此,任何时刻最多只能有一个进程独占打印机,其他进程必须等待该进程释放打印机后才能使用。

这种互斥关系属于间接相互制约(源于资源共享),而非同步关系(源于任务协作)。

下面使用PV操作写出算法。

1 . 定义信号量

设置一个互斥信号量 mutex,用于实现对打印机资源的互斥访问。

semaphore mutex = 1;  // 初始值为1,表示打印机可用

2 . 三个进程的算法结构(伪代码)

每个进程(进程A、进程B、进程C)的算法结构完全相同,只是进程名不同。以进程i为例:

process Pi(i = A, B, C) {

    // ... 进程执行的其他不需要打印机的代码段 ...

    P(mutex);        // 申请使用打印机,若资源不可用则阻塞等待

    // 临界区:使用打印机输出计算结果

    打印计算结果;

    V(mutex);        // 释放打印机,唤醒等待队列中的一个进程

    // ... 进程后续的其余代码 ...

}

3 . 完整描述(文字算法)

初始化一个信号量 S,其值为1。

对于每一个进程,在使用打印机之前执行 P(S) 操作。如果 S 值减1后变为非负数,则该进程获得打印机并进入临界区;如果 S 值减1后为负数,则该进程被阻塞,加入等待队列。

进程完成打印后执行 V(S) 操作。如果 S 值加1后仍小于等于0,则从等待队列中唤醒一个被阻塞的进程(使其转为就绪态);如果加1后大于0,则无等待进程,仅释放资源。

4 . 说明

三个进程之间没有固定的执行顺序要求,任何进程先执行 P 操作且信号量可用时就能先使用打印机。

该算法保证了打印机资源的互斥使用,不会出现多个进程同时打印的情况,也不会发生死锁(因为每个进程只申请一个资源,不存在循环等待)。

如果有进程在等待打印机,当 V 操作执行时,被唤醒的进程将获得打印机(准确说是从阻塞态回到就绪态,由调度程序决定何时实际运行)。

3 、判断下列同步问题的算法是否正确?若有错,请指出错误原因并予以改正。

设A,B两个进程共用一个缓冲区Q,A向Q写入信息,B从Q读出信息,算法框图如图左侧所示。

设A,B为两个并发进程,它们共享一个临界资源。其运行临界区的算法框图如图右侧所示。

https://lms.ouchn.cn/api/uploads/1599585/in-rich-content?created_at=1647446743

答:

①A、B共用一个缓冲区 Q(生产者-消费者单缓冲区)

左侧框图算法描述:

进程 A:向 Q 写入信息 → V(S)

进程 B:P(S) → 从 Q 读出信息

信号量 S 初值为 0

判断:错误。

错误原因:

初值 S = 0 是合理的,表示开始时缓冲区空,B 应先等待。

但 A 的逻辑缺少对缓冲区是否已满的检查。
虽然只有一个缓冲区,A 写一次之后,如果再次写入(未等 B 读),就会发生覆盖。

更严重的是:A 不进行 P 操作,当 B 读完后,不会通知 A 缓冲区空。
正确的单缓冲区同步需要两个信号量:empty(表示空位)和 full(表示有数据)。

改正:

semaphore empty = 1;   // 空闲缓冲区数

semaphore full  = 0;   // 已填满的缓冲区数

A:

P(empty);

向 Q 写入信息;

V(full);

B:

P(full);

从 Q 读出信息;

V(empty);

② A、B 共享一个临界资源(CSa、CSb)

右侧框图算法描述:

进程 A:临界区CSa → V(S1) → P(S2)

进程 B:P(S1) → 临界区CSb → V(S2)

信号量 S1、S2 初值均为 0

判断:错误。

错误原因:

无互斥保证。两个进程不是互斥进入自己的临界区,而是试图强行“同步交替”。
实际上,这个算法只能让 A 先执行 CSa,然后 B 执行 CSb,但若想再让 A 执行第二次 CSa 或让 B 任意次数进入,就会死锁。

初值 S1 = 0 会使 B 一开始就阻塞(P(S1) 不通过),必须先等 A 执行一次 V(S1)。

在 A 执行完 V(S1) 后,B 可以执行 CSb 并 V(S2),然后 A 才能继续(P(S2))。
但此后系统无法让 A 第二次进入 CSa,因为 S1 又被 B 减到 0,且 A 不会再 V(S1),于是死锁。

改正(假设需要互斥访问共享资源):

应该是标准的互斥模式:

semaphore mutex = 1;

A:

P(mutex);

临界区CSa;

V(mutex);

B:

P(mutex);

临界区CSb;

V(mutex);

最终答案总结:

错误。缺少对缓冲区状态的完整同步(应使用 empty/full 两个信号量)。
错误。不能保证互斥,且会导致无法重复进入临界区(会发生死锁或错误顺序)。

4 、设有无穷多个信息,输入进程把信息逐个写入缓冲区,输出进程逐个从缓冲区中取出信息。设缓冲区是环形的,编号为0n-1inout分别是输入进程和输出进程使用的指针,初值都是0

n 为使两类进程实行同步操作,设置了3个信号量:两个计数信号量fullempty,一个互斥信号量mutex

full:表示放有信息的缓冲区数,其初值为( 0 )

empty:表示可供使用的缓冲区数,其初值为( n )

mutex:表示互斥信号量,初值为( 1 )。

填写相应的PV操作。

输入进程Input:

while (TRUE) {

P(empty);          // 申请一个空闲缓冲区,若无则阻塞

     P(mutex);          // 互斥访问缓冲区

信息送往buffer(in);

in=(in+1)mod N; /*以N为模*/

    V(mutex);          // 释放互斥锁

   V(full);           // 增加有数据的缓冲区数量

}

输出进程Output:

while (TRUE){

    P(full);           // 申请一个有数据的缓冲区,若无则阻塞

    P(mutex);          // 互斥访问缓冲区

从buffer(out)中取出信息;

out=(out+1)mod N; /*以N为模*/

V(mutex);          // 释放互斥锁

    V(empty);          // 增加空闲缓冲区数量

}

5 、设有一台计算机,有两条I/O通道,分别接一台卡片输入机和一台打印机。卡片机把一叠卡片逐一输入到缓冲区B1中,加工处理后再搬到缓冲区B2中,并在打印机上打印结果。问:

系统要设几个进程来完成这个任务?各自的工作是什么?

这些进程间有什么样的相互制约关系?

③ 用P、V操作写出这些进程的同步算法。

答:

① 系统要设几个进程来完成这个任务?各自的工作是什么?

可以设 3 个进程:

输入进程(Input)
工作:从卡片输入机读入一张卡片,存入缓冲区 B1。

加工进程(Process)
工作:从 B1 取一张卡片的数据,进行加工处理,结果存入缓冲区 B2。

输出进程(Output)
工作:从 B2 取已加工的数据,在打印机上打印结果。

(假设 B1、B2 的大小分别为 N1、N2)

② 这些进程间的相互制约关系

输入进程 与 加工进程 之间:

同步关系:

B1 空时,加工进程不能从 B1 取数据(必须等输入进程放入数据)。

B1 满时,输入进程不能放入数据(必须等加工进程取走数据)。

加工进程 与 输出进程 之间:

同步关系:

B2 空时,输出进程不能从 B2 取数据(必须等加工进程放入结果)。

B2 满时,加工进程不能放入结果(必须等输出进程取走数据)。

三个进程对各自缓冲区 的访问需要互斥(防止同时修改指针或数组)。

输入进程与加工进程对 B1 的访问互斥。

加工进程与输出进程对 B2 的访问互斥。

由于每个缓冲区只由两个不同进程访问(一个放,一个取),互斥可以用信号量保证,但经典的生产者-消费者解法常把互斥与同步分开处理。

③ 用 P、V 操作写出这些进程的同步算法

定义信号量(设 B1 容量为 M,B2 容量为 N):

semaphore empty1 = M;   // B1 的空闲缓冲区数

semaphore full1  = 0;   // B1 的有数据缓冲区数

semaphore mutex1 = 1;   // 互斥访问 B1 的指针/数据区

semaphore empty2 = N;   // B2 的空闲缓冲区数

semaphore full2  = 0;   // B2 的有数据缓冲区数

semaphore mutex2 = 1;   // 互斥访问 B2 的指针/数据区

输入进程(Input)

while (1) {

    P(empty1);      // 有空位才放

    P(mutex1);      // 互斥访问 B1

    读一张卡片到 B1[in1];

    in1 = (in1 + 1) % M;

    V(mutex1);

    V(full1);       // B1 有数据增加

}

加工进程(Process)

while (1) {

    P(full1);       // B1 有数据才取

    P(mutex1);

    从 B1[out1] 取数据;

    out1 = (out1 + 1) % M;

    V(mutex1);

    V(empty1);      // B1 空位增加

    // 加工处理(假设不需要共享资源,所以不必加锁)

    加工数据得到结果;

    P(empty2);      // B2 有空位才放

    P(mutex2);

    把结果放入 B2[in2];

    in2 = (in2 + 1) % N;

    V(mutex2);

    V(full2);       // B2 有数据增加

}

输出进程(Output)

while (1) {

    P(full2);       // B2 有数据才取

    P(mutex2);

    从 B2[out2] 取数据;

    out2 = (out2 + 1) % N;

    V(mutex2);

    V(empty2);      // B2 空位增加

    打印结果;

}

6 、设有无穷多个信息,输入进程把信息逐个写入缓冲区,输出进程逐个从缓冲区中取出信息。针对下述两种情况:

缓冲区是环形的,最多可容纳n个信息;

缓冲区是无穷大的。

试分别回答下列问题:

输入、输出两组进程读/写缓冲区需要什么条件?

用P、V操作写出输入、输出两组进程的同步算法,并给出信号量含义及初值。

答:

① 输入、输出两组进程读/写缓冲区需要什么条件

情况1:环形缓冲区(容量 = n)

互斥条件:
输入进程与输出进程对缓冲区的指针(in、out)及缓冲区数组的访问必须互斥,防止指针错乱或数据不一致。

同步条件:

输入进程:只有缓冲区有空闲位置(即未满)时才能写入,否则必须等待。

输出进程:只有缓冲区有未读信息(即非空)时才能读取,否则必须等待。

情况2:无穷大缓冲区

互斥条件:同样需要互斥访问缓冲区指针及数据区(虽然是无限大,但仍然是共享数据结构,in 指针需互斥修改)。

同步条件:

输入进程:永远不需要等待(因为缓冲区无限大,总有空间),可直接写入。

输出进程:只有缓冲区非空时才能读取,否则必须等待。

② 用P、V操作写出同步算法

情况1:环形缓冲区(容量 = n

信号量定义与初值:

semaphore empty = n;    // 表示空闲缓冲区数量,初值为 n

semaphore full  = 0;    // 表示有信息的缓冲区数量,初值为 0

semaphore mutex = 1;    // 互斥访问缓冲区和 in/out 指针

输入进程(Input):

while (true) {

    P(empty);          // 申请一个空闲缓冲区(若满则阻塞)

    P(mutex);          // 互斥访问缓冲区

    信息写入 buffer[in];

    in = (in + 1) % n;

    V(mutex);

    V(full);           // 增加有信息缓冲区数量

}

输出进程(Output):

while (true) {

    P(full);           // 申请一个有信息的缓冲区(若空则阻塞)

    P(mutex);

    从 buffer[out] 读信息;

    out = (out + 1) % n;

    V(mutex);

    V(empty);          // 增加空闲缓冲区数量

}

情况2:无穷大缓冲区

信号量定义与初值:

semaphore full  = 0;     // 当前缓冲区中信息个数(初值为0)

semaphore mutex = 1;     // 互斥访问缓冲区指针 in(也可保护缓冲区数组)

// 不需要 empty 信号量,因为容量无限大,生产者永远不必阻塞。

输入进程(Input):

while (true) {

    // 无需 P(empty)

    P(mutex);

    信息写入 buffer[in];

    in = in + 1;       // 不会溢出不需取模

    V(mutex);

    V(full);

}

输出进程(Output):

while (true) {

    P(full);           // 必须有信息才能读

    P(mutex);

    从 buffer[out] 读信息;

    out = out + 1;

    V(mutex);

    // 不需要 V(empty)

}

注意:对无穷大缓冲区,实际实现中存储空间由动态内存分配管理,但仍需互斥访问 in 指针(例如用链表追加新节点)。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐