操作系统PV操作题整理2

1.某进程中有3个并发执行的线程thread1、thread2、thread3,其伪代码如下所示。请添加必要的信号量和P、V操作,要求确保互斥访问临界资源

//复数的结构类型定义
typedef struct
{
	float a;
	float b;
}cnum;

cnum x,y,z; //全局变量

//计算两个复数之和
cnum add( cnum p,cnum q)
{
	cnum s;
	s.a=p.a+q.a;
	s.b=p.b+q.b;
	return s;
}

thread1
{
	cnum w;
	w=add(x,y);
	...
}

thread2
{
	cnum w;
	w=add(y,z);
	...
}

thread3
{
	cnum w;
	w.a=1;
	w.b=2;
	z=add(z,w);
	y=add(y,w);
	...
}

先找出线程在各个变量的互斥关系,并发关系。如果是一读一写或两个都写,那么就是互斥关系。每一个互斥关系都需要一个信号量来调节。

semaphore mutex_y1; //mutex_y1用于thread1和thread3对变量y的互斥访问
semaphore mutex_y2; //mutex-y2用于thread2和thread3对变量y的互斥访问
smeaphore mutex_z;  ///mutex_z用于变量z的互斥访问

//复数的结构类型定义
typedef struct
{
	float a;
	float b;
}cnum;

cnum x,y,z; //全局变量

//计算两个复数之和
cnum add(cnum p,cnum q)
{
	cnum s;
	s.a=p.a+q.a;
	s.b=p.b+q.b;
	return s;
}

thread1
{
	cnum w;
	wait(mutex_y1);
	w=add(x,y);   //thread1 和thread2都有y作为参数,是两个都读,不存在互斥问题,thread1对y的操作是读,thread3对y的操作是既读又写存在互斥
	signal(mutex_y1);
	...
}

thread2
{
	cnum w;
	wait(mutex_y2);
	wait(mutex_z);
	w=add(y,z);  // 同样thread2和thread3对y的操作是读和写,需要互斥,对z的操作也需要互斥
	signal(mutex_z);
	signal(mutex_y2);
	...
}

thread3
{
	cnum w;    //注意:w不是全局变量,只在自己的线程内作用,不属于临界资源
	w.a=1;
	w.b=2;
	wait(mutex_z);
	z=add(z,w);
	signal(mutex_z);
	wait(mutex_y1);
	wait(mutex_y2);
	y=add(y,w);
	signal(mutex_y1);
	signal(mutex_y2);
	...
}

2.有A、B两人通过信箱进行辩论,每个人都从自己的信箱中取得对方的问题,将答案和向对方提出的问题组成一个新邮件放入对方的邮箱中。假设A的信箱最多放M个邮件,B的信箱最多放N个邮件。初始A的信箱有x个邮件,B的信箱有y个邮件。当信箱不空时,辩论者才能从邮箱中取邮件,否则等待。当信箱不满时,辩论者才能将邮件放入信箱中,否则需要等待。

semaphore mutex_A;  //用于对A邮箱的互斥
semaphore mutex_B;  //用于对B邮箱的互斥
semaphore Empty_A;  //A邮箱中还可以放入的邮件数量
semaphore full_A;   //A邮箱中的邮件数量
semaphore Empty_B;  //A邮箱中还可以放入的邮件数量
semaphore full_B;   //B邮箱中的邮件数量

Cobegin{
	A{
		while(true)
		{
			P(full_A);
			P(mutex_A);
			take out a mail from box A;
			V(mutex_A);
			V(Empty_A);
			answer a question and put forward one;
			P(Empty_B);
			P(mutex_B);
			put a new mail in box B;
			V(mutex_B);
			V(full_B);
		}
	}

	B{
		while(true)
		{
			P(full_B);
			P(mutex_B);
			take out a mail from box B;
			V(mutex_B);
			V(Empty_B);
			answer a question and put forward one;
			P(Empty_A);
			P(mutex_A);
			put a new mail in box A;
			V(mutex_A);
			V(full_A);
		}
	}
}end

3.系统中有多个生产者消费者进程,共享一个能存放1000件产品的缓冲区(初始为空)。当缓冲区未满时,生产者进程可以放入一个其生产的产品,否则等待;当缓冲区未空时,消费者进程可以从缓冲区取走一件产品,否则等待。要求一个消费者必须连续取走10件铲平后,其他消费者进程才可以取产品。

semaphore mutex1=1;  //用于实现消费者连续取10个产品的互斥
semaphore mutex2=1;  //用于实现缓冲区访问的互斥
semaphore empty=1000;
semaphore full=0;
producer()
{
	while(1)
	{
		produce a product;
		P(empty);
		P(mutex2);
		put product in the buffer;
		V(mutex2);
		V(full);
	}
}

consumer()
{
	while(1){
		P(mutex1);
		for(int i=0;i<10;++i){
			P(full);
			P(mutex2);
			take out a product from the buffer;
			V(mutex2);
			V(empty);
			consume this product;
		}
		V(mutex1);
	}
}

4.某博物馆最多可容纳500人同时参观,有一个出入口,该初入口一次仅允许一个人通过。

semaphore empty=500;
semaphore mutex=1;

Cobegin
visitor process i:
{
	P(empty);
	P(mutex);
	enter...;
	V(mutex);
	visit...;
	P(mutex);
	get out;
	V(mutex);
	V(empty);
}

5.某银行提供一个服务窗口和10个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上取一个号,取号机一次仅允许一个顾客使用。营业员通过叫号选择一位顾客为其服务。

semaphore empty=10;   //空座位数量
semaphore mutex=1;   //互斥使用取号机
semaphore full=0;    //已经占空位数量
semaphore service=0; //等待叫号

process client i{
	P(empty);  //等空位
	P(mutex);
	take a number from the machine;
	V(mutex);
	V(full);  //通知营业员有新顾客
	P(service);  //等待营业员叫号
	accept serive;
}

process teller{
	while(true){
		P(full); //等待顾客
		V(empty);//离开座位
		V(service); //叫号    //这里我觉得应该是先叫号后离开座位,不过应该不影响
		serve for the client
	}
}

6.P1、P2、P3三个进程互斥使用一个包含N个单元的缓冲区,P1每次produce()一个正整数并用put()放入缓冲区某一空单元中;P2每次用getodd()从缓冲区取出一个奇数,并用countodd()统计奇数个数;P3每次用geteven()从缓冲区取出一个偶数,并用counteven()统计偶数个数。

semaphore mutex=1;
semaphore odd=0,even=0;
semaphore empty=N;
main()
cobegin()
{
	process P1()
	{
		while(true)
		{
			x=produce();
			P(empty);
			P(mutex);
			put();
			V(mutex);
			if(x%2==0)
				V(even);
			else
				V(odd);
		}
	}

	Process P2()
	{
		while(true)
		{
			P(odd);
			P(mutex);
			getodd();
			V(mutex);
			V(empty);
			countodd();
		}
	}

	process P3()
	{
		while(true)
		{
			P(even);
			P(mutex);
			geteven();
			V(mutex);
			V(empty);
			counteven();
		}
	}
}coend;
  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值