该临界区已被锁住,则该进程要等到该临界区开锁之后才有可能获得临界区。但是加锁法存在如下弊端:(1)循环测试锁定位将损耗较多的CPU计算时间;(2)产生不公平现象。为此,P,V原语法采用信号量管理相应临界区的公有资源,信号量的数值仅能由P,V原语操作改变,而P,V原语执行期间不允许中断发生。其过程是这样的,当某个进程正在临界区内执行时,其他进程如果执行了P原语,则该进程并不像lock时那样因进不了临界区而返回到lock的起点,等以后重新执行测试,而是在等待队列中等待由其他进程做V原语操作释放资源后,进入临界区,这时P原语才算真正结束。若有多个进程做P原语操作而进入等待状态之后,一旦有V原语释放资源,则等待进程中的一个进入临界区,其余的继续等待。总之,加锁法是采用反复测试lock而实现互斥的,存在CPU浪费和不公平现像,P.V原语使用了信号量,克服了加锁法的弊端。10.设在书3.6节中所描述的生产者-消费者问题中,其缓冲部分为m个长度相等的有界缓冲区组成,且每次传输数据长度等于有界缓冲区长度以及生产者和消费者可对缓冲区同时操作。重新描述发送过程deposit(data)和接收过程remove(data)。答:设第1块缓冲区的公用信号量为mutex「.保证生产者进程和消费者进程对同一块缓冲区操作的互斥,初值为1。设信号量avail为生产者进程的私用信号量,初值为m。信号量full为消费者进程的私用信号量,初值为0。从而有:deposit(data)BeginP(avail)选择一个空缓冲区iP(mutext[1])送数据入缓冲区1v(full)V(mutext[1])EndRemove(data)BeginP(full)选择一个满缓冲区1P(mutext[ 1 J)取缓冲区i中的数据V(avail)V(mutext[1 ])End11.两进程PA,PB通过两FIF()缓冲区队列连接(如图E1.1),每个缓冲区长度等于传: 9
送消息长度。进程PA,P:之间的通信满足如下条件:(a)至少有一个空缓冲区存在时,相应的发送进程才能发送一个消息。(b)当缓冲队列中至少存在一个非空缓冲区时,相R应的接收避程才能接收一个消息。试描述发送过程 send(i,m)和接收过程receive(i,P-m)。这里i代表缓冲队列。图E1.1答:定义数组buf[o],buf[1],bufempty[o],bufful![1]是P的私有信息量,buffull[o],bufempty[是P的私有信息量。初始时:bufempty[o]=bufempty[1]]=n.(n为缓冲区队列的缓冲区个数)buffull[o]=buffuli[1]=0send(I,m)Beginlocal xP(bufempty[])按FIFO方式选择一个空缓冲区buf[1](x)buf[1](x) =mbuf[(x)置满标记V(bufful[])EndReceive(l.m)BeginLocal xP(buffull[))按FIFO方式选择一个装满数据的缓冲区bufLIJ(x)m = buf[1(x)buf[1](x)置空标记V(bufempty[1])EndP,调用send(0,m)和receive(1.m)P调用send(1,m)和receive(0,m)12.在和控制台通信的例中,设操作员不仅仅回答用户进程所提出的问题,而且还能独立地向各用户进程发出指示。对于这些指示,操作员不要求用户进程回答,但它们享有比其他消息优先传送的优先度。即如果inbuf中如有指示存在,案统不能进行下一次通信会话。试按上迷要求重新描述CCP和KCP,DCP。:10
答:KCP描述如下:设T_Ready和T_Busy分别为键盘KP和键盘控制进程KCP的私有信号量,其初值为0和1。设inbuf为inbuf的共有信号量,初值为1,表示其中没有控制消息。初始化(清除所有inbuf和echobuf)Beginiocal xP(T_Ready)从键盘数据传输缓冲x中取出字符m记为x.tnf为控制消息P(inbuf)Send(x. m)将x.m送入echobufV(T_Busy)End键盘控制进程DCP:repeatP(T_Busy)把键入字符放入数据传输缓冲V(T.Ready)Until终端关闭显示其控制进程DCP:设D_Ready和D_Busy分别为DP和DCP的私有信号量且初值为0和1.初始化(清除输出缓冲outbuf,echo模式置false)Beginif outbuf满thenreceive(k)P(D_Busy)把k送入显示器数据缓冲区V(D.Ready)elseElseEcho模式置trueEchobuf中字符置入显示器数据缓冲区tiEnd显示器动作DP:repeatifecho模式then:11:
打印显示器数据缓冲区中字符elseP(D_Ready)打印显示器数据缓冲区中消息V(D_Busy)Until显示器关机设过程Read(x)把inbuf中的所有字符读到用户进程数据区x处,过程write(y)把用户进程y处的消息写到outbuf中.read(x)和write(y)可分别描述如下:read(x):write(y)略略13.编写一个程序使用来统调用fork生成3个子进程,并使用来统调用pipe创建一管道,使得这3个子进程和进程公用同一管道进行信息通信。答:main()Yinti,.pl.p2,fd[2],/#fa[2]为管道文件读写标识*/char buf[50],s[5];pipe(fd);/*创建管道pipe()*/while((pl =fork(1)=二-1),/*创建子进程1*|if(pl== 0)/*在子进程1中执行*/1lockf(fd[1],1.0),/*锁定写过程*/sprintf(buf,'child process Pl is seding messagel In");printf(child process Pl! n')+write(fd[1],buf,50),/*将buf中数据写入pipe#/sleep(5);/*睡眠等待父进程读出*/lockf(fd[1].o.0);/*解锁*/exit(0),1else(while((p2-fork())=--1)/*创建进程2/if(p2 == 0)/*在子进程2中执行*/美lockf(fa[1].1,0),/ *锁定写过程*/sprintf(buf,child process P2 is sending message! In'), / * 数据入 buf * /printf("child process P21 In");write(fd[1].buf.50),/*buf数据写入pipe*/sleep(5):/*同步等待父进程读*/lockf(fd[1].0.0);/ * 解锁 * /.12
*释放进程资源*exit(0);1elset/*创建进程3*/while((p3fork())==—1)/在子进程3中*/if(p3==0)tlock(fd[1],1,0);sprintf(buf."child process P3 is sending message!In");printf(child process P3!n),write(fd[1],buf,50),sleep(5);lockf(fd[1],0,0);exit(0),1/*父进程等待子进程先执行*/wait(0),/*读管道pipe内容到s中*/if(r=read(fd[o7,s,50)==-1)printf("can't read pipe\n");elseprinti<"%sn"+s);/*等待另一个子进程执行*/wait(0);if(r=read(fd[o~+s.50)==-1)printf("can't read pipeln");elseprintf("%s(n",s);wait(0);/*等待最后一个子进程执行*/if(r=reed(fd[0]s,50)0==-1)printf("can't read pipe n")elseprintf("%s/n".s);exit(0);13+14.设有5个哲学家,共享一张放有五把椅子的桌子,每人分得一把将子。但是,来子上总共只有五只姨子,在每人两边分开各放一只。哲学家们在旺子饥饿时才试图分两次从两边拾起筷子就餐。条件:(1)只有拿到两只旗子时,替学家才能吃饭。(2)如果疑子已在他人手上,则该哲学家必须等到他人吃完之后才能享到筷子。(3)任一哲学家在自已未拿到两只筷子吃饭之前,决不放下自己手中的筷子。:13: