经典PV操作题

重点:
P
1,每执行一次就会减1,减后小于0就要等待(即P(0)就要等待)
2,可以理解为是检查当前这个进程前面的所有东西是否处理好了,然后才到自己运行 。
V
1,每执行一次就加减1。
2,理解为当前进程运行好了,要通知下一个进程了。

题目一:

今有3个并发进程R、M、P,它们共享一个缓冲器B。进程R负责从输入设备读入信息,每读一个记录后把它存放在缓冲器B中。进程M在缓冲器B中加工进程R存入的记录。进程P把加工后的记录打印出来。缓冲器B中每次只能存放一个记录,当记录被加工输出后,缓冲器B中又可以存放一个新的记录。为协调它们的工作,采用PV操作进行管理,请写出R、M、P 三个并发进程的伪代码。要求写出详细的步骤。

信号量 s1=1,s2=0,s3=0;

R(){
	while(1){
		读入信息
		P(s1); //看看是不是到自己运行   
		记录存入缓存器B中 
		V(s2); //通知下一个进程
	}
}
 
M(){
	while(1){
		P(s2);
		加工记录 
		V(s3); 
	}
}

P(){
	while(1){
		P(s3);
		输出信息
		V(s1); //继续通知开头那个进程,形成一个循环,持续工作
	}
}

题目二:

(和题目一类似)
在一个盒子里,混装了数量相等的黑白围棋子。现在用自动分拣系统把黑子、白子分开,设分拣系统有两个进程P1和P2,其中P1拣白子,P2拣黑子。规定每个进程每次拣一子;当进程在拣时,不允许另一个进程取拣;当一个进程拣了一子时,必须让另一进程去捡。假设从拣白子开始。试写出P1和P2进程能正确并发执行的算法程序。要求写出详细的步骤

信号量 s1=1,s2=0;

P1(){
	while(1){
		P(s1);
		拣白子
		V(s2);
	}
}

P2(){
	while(1){
		P(s2);
		拣黑子
		V(s1);
	}
} 

题目三

假定有一个成品仓库,总共能存放8台成品,生产者进程把生产成品放入仓库,消费者进程从仓库中取出成品消费。为了防止积压,仓库满时就停止生产。由于仓库搬运设备只有一套,故成品的存入和取出只能分别进行,试用P、V操作来实现该方案。要求写出详细的步骤。

信号量 s1=8,s2=0,mutex=1

producer(){
	P(s1);//看看仓库还能不能装下成品,能就生产s1--,可以把s1看作仓库剩余的空间
	生产产品
	P(mutex);//搬运设备互斥资源,加锁
	搬运
	V(mutex);//用完,解锁
	V(s2); //通知消费者可以来拿东西
} 

consumer(){
	P(s2);//看看有没有人通知我拿东西
	P(mutex);
	搬运 
	V(mutex);
	V(s1); //通知生产者,我拿东西了,仓库剩余空间+1
}

题目四

某自动质量检测系统有三个进程Q、A、B组成。进程Q每次取一件产品检测,把检测后的产品存放在货架F上,F的容量为每次只能存放一件产品。若货架上存放的是合格产品则让进程A取出,并在产品上贴标签后包装;若货架上存放的是不合格产品则让进程B取出后,将其丢入废物箱。
请写出用PV操作管理时应定义的信号量及初值以及相应的操作,使它们能按上述要求正确地并发执行。

信号量 a=0,b=0,empty=1

Q(){
	取一件产品检查 
	P(empty);//检测货架是否位置
	放在货架F上
	if(产品合格){ //如果合格产品,通知a
		V(a); 
	}
	else{
	    V(b)//否则通知b
	} 
} 

A(){
	P(a);//检测是否有自己的工作
	取货架F的产品 
	V(empty);//拿走产品,位置+1
	对产品贴标签且包装
}

B(){
	P(b);
	取货架F的产品
	V(empty);
	把产品丢入废物箱
} 

题目五

三个进程 P1、P2、P3 互斥使用一个包含 N(N>0)个单元的缓冲区。P1 每次用 produce() 生成一个正整数并用 put()送入缓冲区某一个空单元中;P2 每次用 getodd()从该缓冲区中 取出一个奇数并用 countodd()统计奇数个数;P3 每次用 geteven()从该缓冲区中取出一个 偶数并用 counteven()统计偶数个数。请用信号量机制实现这三个进程的同步与互斥活动, 并说明所定义的信号量的含义。

信号量 even=0,odd=0,empty=N,mutex=1;
int num;
P() {
	while(1) {
		P(empty); //检测是否还有位置
		num=produce();
		P(mutex);//实现缓冲器互斥
		put();
		V(mutex);
		if(num%2==0) {
			V(even);//通知偶数的线程
		} else {
			V(odd);//通知奇数的线程
		}
	}
}

P2() {
	while(1) {
		P(odd); //看看有没有自己奇数的任务
		P(mutex);//用到缓冲器,要互斥
		getodd();
		countodd();
		v(mutex);
		v(empty);//取出一个数,位置+1
	}
}

P3() {
	while(1) {
		P(even);
		P(mutex);
		geteven();
		counteven();
		V(mutex);
		V(empty);
	}
}

题目六

一个野人部落从一个大锅中一起吃炖肉,这个大锅一次可以存放 M 人份的炖肉。当野人 们想吃的时候,如果锅中不空,他们就自助着从大锅中吃肉。如果大锅空了,他们就叫 醒厨师,等待厨师再做一锅肉。 野人线程未同步的代码如下: while (true){ getServingFromPot(); eat() } 厨师线程未同步的代码如下: while (true) { putServingsInPot(M) } 同步的要求是: 当大锅空的时候,野人不能够调用 getServingFromPot() 仅当大锅为空的时候,大厨才能够调用 putServingsInPot() 问题:请写出使用 PV 满足同步要求的完整程序。

//假设一开始锅为空,让厨师煮才有
信号量 empty=1,haveFood=0;
int food=0;
//empty 和 haveFood 分别表示厨师阻塞等待和野人阻塞等待的条件
wildMan(){
	P(haveFood); //检查是否有食物,且锁锅
	getServingFromPot();//拿食物
    food--;//食物数量-1
    eat();//吃
	if(food==0){
		V(empty); //没有食物了,通知厨师煮
	}
	else{
		V(haveFood); //解锅
	}
}

cook(){
	P(empty); //看看自己有没有煮饭任务
	putServingInPot(M); 
    food += M;//煮一锅
    V(haveFood);//v后 +1,让野人检查到锅里有食物(野人通知厨师后没有解锅,厨师要帮忙解锅
} 

题目七

桌子上有一只盘子,最多可容纳两个水果,每次只能放一只水果,爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,两个儿子专等吃盘子里的橘子,两个女儿专等吃盘子里的苹果。写出能使爸爸、妈妈、儿子、女儿正确同步工作的PV过程。

信号量 mutex=1,empty=2,apple=0,orange=0

father(){
	while(1){
		P(empty);//看看是否还有位置放水果
		P(mutex);//对盘子加锁
		放一个苹果
		V(mutex)//解锁
		V(apple)//通知拿苹果的人
	}
}

mother(){
	while(1){
		P(empty);
		P(mutex);
		放一个桔子
		V(mutex)
		V(orange);
	}
}

son(){
	while(1){
		P(orange);
		P(mutex);
		拿一个桔子
		V(mutex);
		V(empty); 
	}
}

daughter(){
	while(1){
		P(apple);//检查自己有没有被通知拿苹果
		P(mutex);//加锁
		拿一个苹果
		V(mutex);//解锁
		V(empty); 
	}
}
  • 3
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值