1、二元信号量只能取0或1,而一般信号量可以取任何整数。5.10强信号量与弱信号量有什么区别。强信号量要求在信号量上等待的进程按照先进先出的规则从队列中移出。弱信号量没有此规则。5.11.什么是管程。管程是由一个或多个过程,一个初始化序列和局部数据组成的软件模块。5.12对于消息,有阻塞和无阻塞有什么区别?5.13.通常与读者-写者问题相关联的有哪些条件?1.任意多的读进程可以同时读这个文件,2.一次只有一个写进程可以往文件中写,3.如果一个写进程正在往文件中写时,则禁止任何读进程读文件。习题:5.1b.协同程序read读卡片,将字符赋给一个只有一个字大小的缓冲区rs然后在赋给squash协同程。
2、协同程序Read在每副卡片图像的后面插入一个额外的空白。协同程序squash不需要知道任何关于输入的八十个字符的结构,它简单的查找成对出现的星号,然后将更改够的字符串经由只有一个字符大小的缓冲sp,传递给协同程序print。最后协同程序print简单的接受到来的字符串,并将他们打印在包含125个字符的行中。5.2考虑一个并发程序,它有两个进程p和q,定义如下。A.B.C.D和E是任意的原子语句。假设住程序执行两个进程的parbegin Void p() void q() A; D; B; E; C; ABCDE;ABDCE;ABDEC;ADBCE;ADBEC;ADEBC;DEABC;DAEBC
3、;DABEC;DABCE;5.3考虑下面的程序 const int n=50; int tally;void total() int count; for(count =1;count =n;count +) tally+;void main() tally =0;parbegin(total(),total();write(tally);a.随意一看,tally值的范围好像是落在50,100这个区间里,因为当没有互斥时可以从0直接增加到50.这一基本论点是当并发的运行这两进程时,我们不可能得到一个比连续执行单一某进程所得tally值还低的一个最终tally值.但是考虑下面由这两进程按交替顺序
4、执行载入,增加,存储的情况,同时变更这个共享变量的取值: 1.进程A载入tally值,tally值加到1,在此时失去处理器(它已经增加寄存器的值到1,但是还没有存储这个值). 2.进程B载入tally值(仍然是0),然后运行完成49次增加操作,在它已经将49这个值存储给共享变量tally后,失去处理器控制权. 3.进程A重新获得处理器控制权去完成它的第一次存储操作(用1去代替先前的49这个tally值),此时被迫立即放弃处理器. 4.进程B重新开始,将1(当前的tally值)载入到它自己的寄存器中,但此时被迫放弃处理器(注意这是B的最后一次载入). 5.进程A被重新安排开始,但这次没有被中断,
5、直到运行完成它剩余的49次载入,增加和存储操作,结果是此时tally值已经是50. 6.进程B在它终止前完成仅有的最后一次增加和存储操作.它的寄存器值增至2,同时存储这个值做为这个共享变量的最终结果. 一些认为会出现低于2这个值的结果,这种情况不会出现.这样tally值的正确范围是2,100. b.对一般有N个进程的情况下,tally值的最终范围是2,N*50,因为对其他所有进程来说,从最初开始运行到在第五步完成.但最后都被进程B破坏掉它们的最终结果.5.4.忙等待是否总是比阻塞等待效率低(根据处理器的使用时间)?请解释。就一般情况来说是对的,因为忙等待消耗无用的指令周期.然而,有一种特殊情况
6、,当进程执行到程序的某一点处,在此处要等待直到条件满足,而正好条件已满足,此时忙等待会立即有结果,然而阻塞等待会消耗操作系统资源在换出与换入进程上.5.5考虑下面的程序 boolean blocked2; int rurn; void P(int id) While (true) While(turn!=id); While(blocked1-!id /*do nothing*/; Turn =id; Void main () Blocked0=false; Blocked1=false; Turn=0; Parbegin(P(0),P(1);这是【HYMA66】中提出的解决互斥问题的一种方法
7、。请举出证明该方法不正确的一个反例。考虑这种情况:此时turn=0,进程P(1)使布尔变量blocked1的值为true,在这时发现布尔变量blocked0的值为false,然后P(0)会将true值赋予blocked0,此时turn=0,P(0)进入临界区,P(1)在将1赋值给turn后,也进入了临界区.5.6解决互斥的另一种软件方法是lamport的面包店(bakery)算法,之所以起这个名字,是因为它的思想来自于面包店或其他商店中,每个顾客在到达时都得到一个有编号的票,并按票号依次得到服务,算法如下: Boolean choosingn; Int numbern; Choosingi=t
8、rue; Numberi=1+getmax(number,n); Choosingi=false; For(int j=0;jn;j+) While (choosingj) While (numberj!=0)&(numberj,j)(numberi,i) /*critical section*/ Numberi=0; /*remainder*/;数组choosing和number分别被初始化成false和0,每个数组的第i个元素可以由进程i读或写,但其他进程只能读。符号(a,b)(c,d)被定义成 (a,c)或(a=c且bd)A用文字描述这个算法。B说明这个算法避免了死锁。C说明它实施了互斥
9、。a.当一个进程希望进入临界区时,它被分配一个票号.分配的票号是通过在目前那些等待进入临界区的进程所持票号和已经在临界区的进程所持票号比较,所得最大票号再加1得到的.有最小票号的进程有最高的优先级进入临界区.当有多个进程拥有同样的票号时,拥有最小数字号进入临界区.当一个进程退出临界区时,重新设置它的票号为0. b.如果每个进程被分配唯一的一个进程号,那么总会有一个唯一的,严格的进程顺序.因此,死锁可以避免. c.为了说明互斥,我们首先需要证明下面的定理:如果Pi在它的临界区,Pk已经计算出来它的numberk,并试图进入临界区,此时就有下面的关系式: ( numberi, i ) ( numb
10、erk, k ).为证明定理,定义下面一些时间量: Tw1:Pi最后一次读choosingk, 当 j=k,在它的第一次等待时,因此我们在Tw1处有choosingk = false. Tw2:Pi开始它的最后执行, 当j=k,在它的第二次while循环时,因此我们有Tw1 Tw2. Tk1:Pk在开始repeat循环时;Tk2:Pk完成numberk的计算;Tk3: Pk设置choosingk为false时.我们有Tk1Tk2Tk3.因为在Tw1处,choosingk=false,我们要么有Tw1Tk1,要么有Tk3Tw1.在第一种情况中,我们有numberinumberk,因为Pi在Pk之
11、前被分配号码;这个满足定理条件.在第二种情况中,我们有Tk2 Tk3 Tw1 Tw2,因此有Tk2Tw2.这意味着在Tw2时,Pi已经读了当前numberk的值.而且,因为Tw2是当j=k第二次while循环执行发生的时刻,我们有(numberi, i ) ( numberk, k),这样完成了定理的证明.现在就很容易说明实施了互斥.假定Pi在临界区,Pk正试图进入临界区.Pk将不能进入临界区,因为它会发现numberi不等于0,并且( numberi, i ) ( numberk, k ).5.7当按图5.2的形式使用一个专门机器指令提供互斥时,对进程在允许访问临界区之前必须等待多久没有控制
12、。设计一个使用testset指令的算法,且保证任何一个等待进入临界区的进程在n-1个turn内进入,n是要求访问临界区的进程数,turn是指一个进程离开临界区而另一个进程获准访问这个一个事件。以下的程序由SILB98提供:var j: 0.n-1;key: boolean;repeatwaitingi := true;key :while waitingi and key do key := testset(lock);= false;j := i + 1 mod n;while (j i) and (not waitingj) do j := j + 1 mod n;if j = i the
13、n lock := falseelse waiting : remainder section Until这个算法用最普通的数据结构:var waiting: array 0.n 1 of boolean Lock:boolean这些数据结构被初始化成假的,当一个进程离开它的临界区,它就搜索waiting的循环队列5.8考虑下面关于信号量的定义: Void semWait(s) If (s.count0) s.count-; Else Place this process in s.queue; Block; Void semSignal(s) If (there is at liast on
14、e process blocked on semaphore) Remove a process P from s.queue; Place process P on ready list; Else s.count+;比较这个定义和图5.3中的定义,注意有这样的一个区别:在前面的定义中,信号量永远不会取负值。当在程序中分别使用这两种定义时,其效果有什么不同?也就是说,是否可以在不改变程序意义的前提下,用一个定义代替另一个?这两个定义是等价的,在图5.3的定义中,当信号量的值为负值时,它的值代表了有多少个进程在等待;在此题中的定义中,虽然你没有关于这方面的信息,但是这两个版本的函数是一样的。
15、5.9可以用二元信号量实现一般信号量。我们使用semWaitB操作和semSignalB操作以及两个二元信号量delay和mutex。考虑下面的代码 Void semWait(semaphor s) semWaitB(mutex); s-; if (s semSignalB(mutex); semWaitB(delay); Semsignalb(mutex) Void semSignal(semaphore s); s+; if(s;if nm = 0 then semSignal(a)else semSignal(m)5.11下面的问题曾被用于一个测试中:侏罗纪公园有一个恐龙博物馆和一个公园
16、,有m个旅客和n辆车,每辆车只能容纳一名旅客。旅客在博物馆逛了一会儿,然后派对乘坐旅客车。当一辆车可用时,它载入一名旅客,然后绕公园行驶任意长的时间。如果n辆车都已被旅客乘坐游玩,则想坐车的旅客需要等待;如果一辆车已经就绪,但没有旅客等待,那么这辆车等待。使用信号量同步m个旅客进程和n个进程。下面的代码框架是在教室的地板上发现的。忽略语法错误和丢掉的变量声明,请判定它是否正确。注意,p和v分别对应于semwait和semsignal。 Resource Jurassic_Park()Sem car_avail:=0,car_taken:=0,car_fillde:=0.passenger_re
17、leased:=0Process passenger(i:=1 to num_passengers) Do true-nap(int(random(1000*wander_time) P(car avail);V(car_taken);P(car_filled) P(passenger_released) Od End passenger Process car(j:=1 to num_cars)V(car_avail);P(car_taken);V(car_filled) Nap(int(random(1000*ride_time) V(passenger_released) Od End
18、car End Jurassic_Park这段代码有一个重要问题.在process car中的代码 V(passenger_released)能够解除下面一种旅客的阻塞,被阻塞在P(passenger_released)的这种旅客不是坐在执行V()的车里的旅客.5.12在图5.9和5.3的注释中,有一句话是“仅把消费者临界区(由s控制)中的控制语句移出还是不能解决问题,因为这将导致死锁”,请用类似于表5.3的表说明。ProducerConsumersndelay12SemWaitB(S)3n+4If(n=1)(semSignalB(delay)5semSignalB(s)6semWaitB(d
19、elay)7semWaitB(s)8n-9If(n=0) (semWaitB(delay)10生产者和消费者都被阻塞。5.13考虑图5.10中定义的无限缓冲区生产者/消费者问题的解决方案。假设生产者和消费者都以大致相同的速度运行,运行情况如下: 生产者:append;semSignal;produce;semSignal 消费者:consume;take;semWait;生产者通常管理给换成区一个元素,并在消费者消费了前面的元素后发信号。生产者通常添加到一个空缓冲去中,而消费者通常取走缓冲区中的唯一元素。尽管消费者从不在信号量上阻塞,但必须进行大量的信号量调用,从而产生相当多的开销。构造一个新
20、程序使得能在这种情况下更加有效。允许n的值为-1,这表示不仅缓冲区为空,而且消费者也检测到这个事实并将被阻塞,直到生产者产生新数据。这个方案不需要使用图5.10中的局部变量m。这个程序来自于BEN82program producerconsumer;var n: integer;s: (*binary*) semaphore (:= 1);delay:= 0);procedure producer;beginsemWaitB(s);n := n + 1;if n=0 then semSignalB(delay);foreverend;procedure consumer;= n 1;if n
21、= -1 thensemSignalB(s);semWaitB(delay);begin (*main program*)parbeginproducer; consumerparendend.5.14考虑图5.13.如果发生下面的交换,程序的意义是否会发生改变?a.semWait(e);semWait(s)b.semSignal(s);semSignal(n)c.semWait(n);d.semSignal(s);semSignal(e)只要交换顺序都会导致程序错误。信号量s控制进入临界区,你只想让临界区区域包括附加或采取功能。5.15在讨论有限缓冲区(见图5.12)生产者/消费者问题时,注意我们的定义允许缓冲区中最多有n-1个入口? a.这是为什么? b.请修改程序,以不久这种低调?如果缓冲区可以容纳n个入口,问题在于如何从一个满
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1