操作系统---PV操作题分析(持续更新)

1.某寺庙有小和尚、老和尚若干,有一水缸,由小和尚提水入缸供老和尚饮用。水缸可容10桶水,水取自同一井中。水井径窄,每次只能容一个桶取水。水桶总数为3个。每次入缸取水仅为1桶水,且不可同时进行。试给出有关从缸取水、入水的算法描述。

从井中取水并放入水缸是一个连续的动作,可视为一个进程;从缸中取水可视为另一个进程。设水井和水缸为临界资源,引入 well 和 vat:三个水桶无论是从井中取水还是将水倒入水缸都是一次一个,应该给它们一个信号量pail,抢不到水桶的进程只好等待。水缸满时,不可以再放水,设置 empty 信号量来控制入水量;水缸空时,不可以取水,设置 full 信号量来控制。本题需要设置5个信号量来进行控制:

semaphore well=1;        //1个水井

semaphore vat=1;        //1个水缸

pail=3;        //3个水桶

empty=10;        //水缸中的剩余空间能容纳的水的桶数,初值为10

full=0;        //表示能从水缸中取走的水的桶数,初始水缸没水,处值为0

//小和尚

while(1){

        P(empty);        //检查水缸里能不能放水

        P(pail);        //能放水,则拿桶,桶-1

        P(well);        //到井中打水

        从井中打水;

        V(well);        //打完水,释放“井”互斥资源

        P(vat);        //将水倒入缸中

        将水倒入缸中;

        V(vat);        //倒完后,释放“水缸”互斥资源

        V(full);        //缸中水的桶数+1

        V(pail);        //使用完桶放回,桶+1

}

//老和尚

while(1){

        P(full);        //检查水缸中是否有水

        P(pail);        //拿桶装水

        P(vat);        //使用“水缸”互斥资源

        从缸中取水;

        V(vat);        //释放互斥资源

        V(empty);   //水缸中的剩余空间+1

        喝水;       

        V(pail);        //把桶放回

}

2.如下图所示,三个合作进程P1,P2,P3,它们都需要通过同一设备输入各自的数据a,b,c,该输入设备必须互斥地使用,而且其第一个数据(a)必须由P1进程读取,第二个数据(b)必须由P2进程读取,第三个数据(c)必须由P3进程读取。然后,三个进程分别对输入数据进行下列计算:

最后,P1进程通过所连接的打印机将计算结果x,y,z的值打印出来。请用信号量实现它们的同步。

分析:

进程P1需要用到进程P1读取的a,进程P2读取的b:x=a+b

进程P2需要用到进程P1读取的a,进程P2读取的b:y=a*b

进程P3需要用到进程P2计算的结果y,进程P3读取的数据c,以及进程P1读取的数据a

所以:

P1进程在计算前,需要先确保已经输入了b,其他同理。

这里我们设置S1,S2,S3三个信号量,并将S1初值设为1,S2,S3初值设为0,这样就不用为输入设备专门设置互斥信号量了。但是这样设置就是默认三个进程中P1最先执行。信号量Sb,Sy,Sz分别表示是否已经输入b,以及y,z是否已经计算完成。Sb,Sy,Sz初值为0

P1(){

        P(S1);        //使用输入设备

        输入数据a;

        V(S2);        //S2+1,表示接下来P2可以使用输入设备

        P(Sb);        //检查数据b有没有输入

        x=a+b;

        P(Sy);        //检查y是否完成计算

        P(Sz);        //检查z是否完成计算

        使用打印机打印出x,y,z的结果;

}

P2(){

        P(S2);

        输入数据b;

        V(S3);        //S3+1,表示接下来P3可以使用输入设备

        V(Sb);        //表示b已经输入,可以正常进行P(Sb)了

        y=a*b;

        V(Sy);       //Sy已经计算完成,可以正常执行P(Sy)了

}

P3(){

        P(P3);

        输入数据c;

        P(Sy);        //检查y是否已经计算完成

        z=y+c-a;

        V(Sz);        //可以执行P(Sz)

}

注意几点:

(1) 为什么P2,P3进程计算之前不需要P(S1)了,因为设置初值的时候我们把P1=1,P1最先执行,数据a最先输入,所以不需要检查数据a有没有输入

(2) 而P1执行时,就需要先检查b是否已经输入,即P(S2),所以进程实际执行的顺序:

① P1进程执行到P(Sb),发现Sb=0,不能继续往下执行

② 执行P2进程,P2进程V(Sb)

③ P1进程继续执行,直到P(Sz),Sz=0,堵塞

④ 执行P3进程,V(Sz)

⑤ P1继续执行

总之就是先V后P,一定要先V资源后,才能P资源

3.有桥如下图所示。车流方向如箭头所示。回答如下问题:

(1)假设桥上每次只能有一辆车行驶,试用信号灯的PV操作实现交通管理。

semaphore bridge=1;

NtoS(){

        P(bridge);

        通过桥;

        V(bridge);

}

StoN(){

        P(bridge);

        通过桥;

        V(bridge);

}

(2)假设桥上不允许两车交会,但允许同方向多辆车一次通过(桥上可有多辆同方向行驶的车)。试用信号灯的PV操作实现桥上的交通管理。

桥上可以同方向多车行驶,需要设置 bridge,还需要对同方向车辆计数。为了防止同方向计数中同时申请 bridge 造成同方向不可同时行车的问题,要对计数过程加以保护,因此设置信号量mutexSN和mutexNS。

int countSN=0;        //从南向北的汽车数量

int countNS=0;        //从北向南的汽车数量

semaphore mutexSN=1;        //保护countSN

semaphore mutexNS=1;        //保护countNS

semaphore bridge=1;        //互斥信号量

StoN(){               //从南向北的汽车

        P(mutexSN);

        if(countSN==0)

                P(bridge);

        countSN++;

        V(mutexSN);        

        过桥;

        P(mutexSN);

        countSN--;

        if(countSN==0)

                V(bridge);

        V(mutexSN);

}

NtoS(){        //从北向南的汽车

        P(mutexNS);

        if(countNS==0)

                P(bridge);

        countNS++;

        V(mutexNS);        

        过桥;

        P(mutexNS);

        countNS--;

        if(countNS==0)

                V(bridge);

        V(mutexNS);

}

以StoN为例,若这里没有设置mutexSN,如果有多辆自南向北的车同时经过桥,那么都会检测到countSN=0,并且P(bridge),而bridge=1,只有1辆车能申请到bridge,其他车则不能经过桥,达不到题目的要求。

        if(countSN==0)

                P(bridge);

        countSN++;

加入mutexSN:mutexSN=1,若有多辆自南向北的车同时经过桥,一辆车能成功执行P(mutexSN)并申请(bridge),成功记录该车后(countSN++),其他自南向北的车进程就会跳过if判断,不会被堵塞在P(bridge)。

        P(mutexSN);

        if(countSN==0)

                P(bridge);

        countSN++;

        V(mutexSN);      

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值