生产者消费者问题--练习题目

10-os考研题目


改题目中p0,p1两个进程可以互斥的进入临界区,会出现饥饿现象(答案给的是D,但是自我认为可以出现饥饿现象)

互斥的访问:

p0: Flag[0]=TRUE;
p1: Flag[1]=TRUE;
p1: turn=0; 
p1: While (flag[0] && (turn==0)); // p1 会一直循环
p0: turn=1;// 此时的p1循环条件不满足,进入临界区 
p0: While (flag[1] && (turn==1));  //p0 会一直循环
当p1从临界区出来是flag[1] =false;p0的循环条件不满足p0进入临界区

上述过程完成了p1先进入临界区,之后p0进入临界区,互斥的访问。

这个过程中turn是共享变量,因此一次只能是一个值,一个满足继续循环,一个不满足必然要进入临界区。

存在饥饿: 

p0: Flag[0]=TRUE; 
p1: Flag[1]=TRUE;  
p1: turn=0; 
p1: While (flag[0] && (turn==0));//p1 空等 
p0: turn=1; 
p0: While (flag[1] && (turn==1));//p0 空等 
11-os考研

某银行提供1个服务窗口和10个顾客等待座位。顾客到达银行时,若有空座位,则到取号机领取一个号,等待叫号。取号机每次仅允许一个顾客使用。当营业员空闲时,通过叫号选取一位顾客,并为其服务。顾客和营业员的活动过程描述如下:

cobegin{
	process 顾客i  
	{
		从取号机获得一个号码;
		等待叫号;
		获得服务; 
 	}
	process 营业员  
	{
		while(true) 
		{
			叫号;
			为顾客服务;
		}
	} 
}coend

请添加必要的信号量和P、V(或wait()、signal())操作实现上述过程的互斥和同步。要求写出完整的过程,说明信号量的含义并赋初值。

解析:在这个过程中,顾客到达银行后,需要看是否有空座位,wait(empty)取号服务需要互斥的访问,获得服务之后相应的要释放座位,营业员在有顾客之后才能够进行服务,由于营业员只有一个因此不用互斥的叫号。

semaphore seets=10; //表示空余座位数量的资源信号量,初值为10 
semaphore mutex=1; //互斥信号量,初值为1,用于实现对取号机的互斥访问 
semaphore custom=0; //表示顾客数量的资源信号量,初值为0 cobegin { 
process 顾客i 
{  
	P(seets);
	P(mutex);
	从取号机获得一个号码;   
	V(mutex);
	V(custom);
	等待叫号;
	V(seets);
	获得服务;
} 
process 营业员 
{  
	while(TRUE)  
	{   
		P(custom);   
		叫号;
		为顾客服务;  
	} 
} 
2000-南京大学

桌上有1空盘,允许存放1个水果。爸爸向盘中放苹果,也可以向盘中放桔子。儿子专等吃盘中的桔子,女儿专等吃盘中的苹果。规定当盘空时一次只能放1个水果供吃者取用。

请用wait( )、signal( )原语实现爸爸、儿子、女儿三个并发进程的同步。

解析:可以将上述的问题抽象为生产者消费者模型,其中爸爸是生产者,而对于儿子和女儿来说就是消费者了,因此可以描述成如下图所示的场景:

解:设三个信号量:

plate --- 盘子是否为空,初值为1;

orange --- 盘中是否有桔子,初值为0;

apple --- 盘中是否有苹果,初值为0;

semaphore plate = 1;// 作为盘子的互斥访问信号量
semaphore orange = 0;// 作为橘子信号量
semaphore apple = 0;// 作为苹果信号量 
void father()
{
	while(true)
	{
		wait(plate);
		// 放一种水果
		if(fruit==orange)
			signal(orange);
		else
			signal(apple);
	}
}
void son()
{
	while(true)
	{
		wait(orange);
		// 吃水果
		signal(plate);
	}
}
void daughter()
{
	while(true)
	{
		wait(apple);
		// 吃水果
		signal(plate);
	}
}
经典例题

如图所示,有多个PUT操作同时向BUFF1放数据,有一个MOVE操作不断地将BUFF1的数据移到BUFF2,有多个GET操作不断地从BUFF2中将数据取走。BUFF1的容量为m,BUFF2的容量是n,PUT、MOVE、GET每次操作一个数据,在操作的过程中要保证数据不丢失。试用P、V原语协调PUT、MOVE的操作,并说明每个信号量的含义和初值。

【解析】这里存在两个一般意义的“生产者—消费者”问题,PUT(生产者)与MOVE(消费者)之间,需要设置三个信号量;MOVE(生产者)与GET(消费者)之间,需要设置三个信号量。PUT进程套用生产者进程即可,MOVE进程只有在Buff1有新数据且Buff2有空闲区的时候才移动数据,GET进程套用消费者进程即可。

答案:设置6个信号量full1、empty1、mutex1、full2、empty2、mutex2,它们的含义和初值如下:

  • full1表示Buff1是否有数据,初值为0;
  • empty1表示Buff1有空间,初值为m;
  • mutex1表示Buff1是否可操作,初值为1;
  • full2表示Buff2是否有数据,初值为0;
  • empty2表示Buff2有空间,初值为n;
  • mutex2表示Buff2是否可操作,初值为1;
semaphore empty1 = m;// 作为确定buffer1是否有位置
semaphore empty2 = n;// 作为确定buffer2是否有位置
semaphore full1 = 0;// 作为put->move的同步信号量
semaphore full2 = 0;// 作为move->get的同步信号量
semaphore mutex1 = 1;// 作为buffer1的互斥信号量
semaphore mutex2 = 1;// 作为buffer2的互斥信号量
void put()
{
	while(true)
	{
		wait(empty1);
		wait(mutex1);
		// put
		signal(mutex1);
		signal(full1);
	}
}
void move()
{
	while(true)
	{
		wait(full1);
		wait(empty2);
		wait(mutex1);
		wait(mutex2);
		// move
		signal(mutex1);
		signal(mutex2);
		signal(empty1);
		signal(full2);
	}
}
void get()
{
	while(true)
	{
		wait(full2);
		wait(mutex2);
		// get
		signal(mutex3);
		signal(empty2);
	}
}
【北京航天航空大学2001】

面包店有很多面包,由n个销售人员推销。每个顾客进店后先取一个号,并且等待叫号。当一个销售人员空闲下来时,就叫下一个号。试设计一个使销售人员和顾客同步的算法。


semaphore mutex=1, empty=∞, full=0;
//mutex:对顾客队列(缓冲区)进行互斥操作的信号量
//empty:缓冲区的空闲容量(队列中的还能容纳的顾客数)。
//full:缓冲区已占容量(队列中的顾客数)
void consumer()
{
	while(true)
	{
		wait(empty);
		wait(mutex);
		// 取号
		signal(mutex);
		signal(full);
	}
}
void producer()
{
	while(true)
	{
		wait(full);
		wait(mutex);
		// 服务
		signal(mutex);
		signal(empty);
	}
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值