操作系统原理与实践教程(第二版)习题答案 下载本文

1. 空闲让进。当无进程处于临界区时,允许进程进入临界区,并且只能在临界区运行

有限的时间。

2. 忙则等待。当有一个进程在临界区时,其它欲进入临界区的进程必须等待,以保证

进程互斥地访问临界资源。

3. 有限等待。对要求访问临界资源的进程,应保证进程能在有限时间内进入临界区,

以免陷入“饥饿”状态。

4. 让权等待。当进程不能进入临界区时,应立即放弃占用CPU,以使其它进程有机会得到CPU的使用权,以免陷入“饥饿”状态。

(4) 整型信号量是否能完全遵循同步机构的四条基本准则?为什么?

解:

不能。在整型信号量机制中,未遵循“让权等待”的准则。

(5) 在生产者-消费者问题中,若缺少了V(full)或V(empty),对进程的执行有什么影响?

解:

如果缺少了V(full),那么表明从第一个生产者进程开始就没有对信号量full值改变,即使缓冲池存放的产品已满了,但full的值还是0,这样消费者进程在执行P(full)时会认为缓冲池是空的而取不到产品,那么消费者进程则会一直处于等待状态。

如果缺少了V(empty),例如在生产者进程向n个缓冲区放满产品后消费者进程才开始从中取产品,这时empty=0,full=n,那么每当消费者进程取走一个产品时empty并没有被改变,直到缓冲池中的产品都取走了,empty的值也一直是0,即使目前缓冲池有n个空缓冲区,生产者进程要想再往缓冲池中投放产品会因申请不到空缓冲区而被阻塞。 (6) 在生产者-消费者问题中,若将P(full)和P(empty)交换位置,或将V(full)或V(empty)交换位置,对进程执行有什么影响?

解:

对full和empty信号量的P、V操作应分别出现在合作进程中,这样做的目的是能正确表征各进程对临界资源的使用情况,保证正确的进程通信联络。 (7) 利用信号量写出不会出现死锁的哲学家进餐问题的算法。

解:

对哲学家按顺序从0到4编号,哲学家i左边的筷子的编号为i,哲学家右边的筷子的编号为(i+1)%5。

semaphore chopstick[5]={1};

//定义信号量数组chopstick[5],由于侉子是临街资源(互斥),故设置初值均为1。 Pi(){

//i号哲学家的进程 do{

if(i<(i+1)%5) {

wait(chopstick[i]);

wait(chopstick[(i+1)%5]); } else {

wait(chopstick[(i+1)%5]); wait(chopstick[i]); }

eat

signal(chopstick[i]);

signal(chopstick[(i+1)%5]); think }while(1); }

(8) 利用AND型信号量和管程解决生产者-消费者问题。

解:

利用AND信号量解决生产者-消费者问题的算法描述如下: var mutex,empty,full: semaphore:=1,n,0;

buffer: array[0,...,n-1] of item; in out: integer := 0, 0; begin

parbegin

producer: begin repeat . . .

produce an item in nextp; . . .

Swait(empty, mutex); buffer(in) := nextp; in := (in+1) mod n; Ssignal(mutex, full); until false; end

consumer: begin repeat

Swait(full, mutex); nextc := buffer(out); out := (out+1) mod n; Ssignal(mutex, empty); consume the item in nextc; until false; end parend end

利用管程机制解决生产者-消费者问题,首先需要建立一个管程ProducerConsumer,其中包含两个过程insert(item)和consumer(item)。生产者-消费者同步问题可以用伪代码描述如下:

monitor ProducerConsumer

condition full,empty; int count; void insert(int item) { if (count==N) wait(full); insert(item); count=count+1; if (count==1) signal(empty); } int remover() { if (count==0) wait(empty); remove=remove_item; count=count-1; if (count==N-1) signal(full); } count=0; end monitor void producer() { while (true) { item=produce_item; ProducerConsumer.insert(item); } }

void consumer() { while (true) { item=ProducerConsumer.remove; consume(item) } }

(9) 进程的高级通信机制有哪些?请简要说明。

解:

进程的高级通信机制分为三大类:共享存储系统、消息传递系统和管道通信系统。 1. 共享存储器系统:在共享存储器系统中,相互通信的进程通过共享某些数据结构或

共享存储区实现进程之间的通信。该系统又可进一步细分为两种方式:基于共享数据结构的通信方式和基于共享存储区的通信方式。

2. 消息传递系统:消息传递机制可以实现不同主机间多个CPU上进程的通信。这种

方式需要使用两条原语send和receive来发送和接收格式化的消息(message)。 3. 管道通信系统:管道通信是一种以文件系统为基础实现的适用于在进程之间实现大

量数据传送的通信方式。

(10) 什么是死锁?产生死锁的原因和必要条件是什么?

解:

所谓死锁是指在一个进程集合中的所有进程都在等待只能由该集合中的其它一个进程才能引发的事件而无限期地僵持下去的局面。

产生死锁的原因可以归结为两点:1)竞争资源, 2)各进程之间的推进顺序不当。 产生死锁的必要条件有四个:1)互斥条件, 2)不剥夺条件, 3)请求和保持条件, 4)环路条件。

(11) 死锁的预防策略有哪些?请简要说明。

解:

死锁的预防策略有三,说明如下:

1. 摒弃请求和保持条件:为摒弃请求和保持条件,系统中需要使用静态资源分配法,

该方法规定每一个进程在开始运行前都必须一次性地申请其在整个运行过程中所需的全部资源。此时,若系统有足够的资源,就把进程需要的全部资源一次性地分配给它;若不能全部满足进程的资源请求,则一个资源也不分给它,即使有部分资源处于空闲状态也不分配给该进程。这样,当一个进程申请某个资源时,它不能占有其它任何资源,在进程运行过程中也不会再提出资源请求。这种方法破坏了请求和保持条件,从而避免死锁的发生。 2. 摒弃不剥夺条件:要摒弃“不剥夺条件”,可以使用如下策略:进程在需要资源时

才提出请求,并且进程是逐个地申请所需资源,如果一个进程已经拥有了部分资源,然后又申请另一个资源而不可得时,其现有资源必须全部释放。在这种方法中,进程只能在获得其原有资源和所申请的新资源时才能继续执行。 3. 摒弃环路等待条件:为确保环路等待条件不成立,可以在系统中实行资源有序分配

策略,即系统中的所有资源按类型被赋予一个唯一的编号,每个进程只能按编号的升序申请资源。

(12) 某系统中有A、B、C、D四类资源,且其总数量都是8个。某时刻系统中有5个进程,判断下列资源状态是否安全?若进程P2申请资源(1,1,1,1),能否为其分配?

进程 P0 P1 P2 P3 P4 Need A B C D 0 0 4 3 2 6 3 0 3 2 1 5 4 0 2 0 0 5 5 4 Allocation A B C D 0 0 2 2 1 1 0 0 2 1 0 3 2 0 0 0 0 2 2 2 解:

现在对该时刻的状态进行安全分析: 由于Available向量为(3,4,4,1),所以Work向量初始化为(3,4,4,1) 此时的Work小于任意的Need[i]向量,所以系统处于不安全状态

由于Request2(1,1,1,1)

Allocation A P0 0 B 0 C 2 D 2 Need A 0 B 0 C 4 D 3 Available A B C D