PV操作经典例题

一、 生产者-消费者问题

【生产者与消费者的同步关系】
生产者:
当有界缓冲区中无空位置时,要等待;
向有界缓冲区放入物品后,要发消息。

消费者:
当有界缓冲区中无物品时,要等待;
从有界缓冲区取出物品后,要发消息。

【解答步骤】

  • 分析关系:找到有几个进程,分析他们之间的同步与互斥关系
  • 大概框架:根据各进程的操作确定大概顺序
  • 信号灯设置:
    两个同步信号灯(S empty:表示空缓冲区数目,初值为n;S full:表示缓冲区满的数目,初值为0)
    一个互斥信号灯(mutex:表示有界缓冲区是否被占用,初值为1,一般互斥都是1)

【程序描述】

//设置信号量
main()
{
semaphore mutex = 1;  //互斥信号量,实现对缓冲区的互斥访问
semaphore empty = n;  //同步信号量,空闲缓冲区的数量
semaphore full = 0;  //同步信号量,产品数量/非空缓冲区的数量

cobegin
	p1();p2();  //p为生产者
	c1();c2();  //c为消费者
coend
}

pi()
{
	while(1)  //生产未完成
	{
		生产一个产品;
		P(empty);  //消耗一个空闲缓冲区
		P(mutex);  //实现互斥是保证在同一进程中进行一对PV操作
		把产品送到有界缓冲区;
		V(mutex);
		V(full);  //增加一个产品,实现同步!
	}
}

ci()
{
	while(1)  //生产未完成
	{
		生产一个产品;
		P(full);  //消耗一个产品,实现与生产者的同步!
		P(mutex);
		从有界缓冲区取出一个产品;
		V(mutex);  
		V(empty);  //增加一个空闲缓冲区
		消费一个产品;
	}
}

提醒:
①实现互斥的P操作一定要在实现同步的P操作之后(否则会造成死锁!)
②两个V操作不会导致进程阻塞,故可以交换!

二、读者-写者问题

【问题描述】
一个数据对象可以为多个并发进程所共享。其中有的进程可能只需要读共享对象的内容,而其他进程可能要更新共享对象(即读和写)。
读读不互斥;读写、写写互斥。

1.读者优先

仅当无读者等待时,才允许写者执行,即读者优先

【程序描述】

//第一读者-写者问题
main()
{
	semaphore wrt = 1;  //互斥信号量,写者与其他读者/写者互斥的访问
	semaphore mutex = 1;  //互斥信号量,互斥访问临界资源readcount
	int readcount = 0;  //记录目前的读者数
	cobegin
		Reader1();
		Reader2();
		...
		Writer1();
		Writer2();
	coend
}

Writer()
{
	while(1)
	{
		P(wrt);  //互斥语句,或写成wait(wrt);
		写者执行;
		V(wrt);  //互斥语句,或写成signal(wrt);
	}
}

Reader()
{
	while(1)
	{
		P(mutex);  //PV保护临界资源
		readcount++;  //读者进后读者数+1
		if(readcount == 1)  
			P(wrt);  //第一个读者判断有无写者,有就进不了,没有就可以进并且阻塞写者
		V(mutex);
		
		读者执行;
		
		P(mutex);
		readcount--;
		if(readcount == 0)
			V(wrt);  //当没有读者,则写者可进
		V(mutex);
	}
}

2.写者优先(相对公平)

在读者与写者同时申请资源的时候,写者优先
(插后面未运行的读者的队而不是正在运行的读者的队)

【程序描述】

//第二读者-写者问题
main()
{
	semaphore wrt = 1;  //互斥信号量,写者与其他读者/写者互斥的访问
	semaphore mutex = 1;  //互斥信号量,互斥访问临界资源readcount
	semaphore w = 1;  //用于实现"写"优先
	int readcount = 0;  //记录目前的读者数
	cobegin
		Writer1();
		Writer2();
		...
		Reader1();
		Reader2();
	coend
}

Writer()
{
	while(1)
	{
		P(w);  //申请读取权限
		P(wrt);
		写者执行;
		V(wrt);
		V(w);  //释放读取权限
	}
}

Reader()
{
	whlie(1)
	{
		P(w);  //申请不到权限则一直等待
		P(mutex);  //多个读者互斥
		if(readcount == 1)  //第一个读者判断有无写者,有就进不了,没有就可以进并且阻塞写者
			P(wrt);
		readcount++;
		V(mutex);  //释放互斥信号量
		V(w);
		
		读者执行;
		
		P(mutex);
		readcount--;
		if(readcount == 0)
			V(wrt);
		V(mutex);
	}
}

三、哲学家进餐问题

【问题描述】
在这里插入图片描述
【问题分析】

  • 筷子是临界资源,因为在一段时间内只允许一位哲学家使用
  • 筷子的互斥使用:一个信号量表示一只筷子,五只筷子构成信号量数组semaphore chopstick[5] = {1,1,1,1,1} //初始化为1

【程序描述】

semaphore chopstick[5] = {11111}  //初始化为1

Pi()  //第i位哲学家结构
{
	do {
		wait(chopstick[i]);  //取左筷子i
		wait(chopstick[(i + 1) % 5]);  //因为是圆桌,若i=0则i的右手边为第5根筷子
		…
		吃饭;signal(chopstick[i]);
		signal(chopstick[(i + 1) % 5]);
		…
		思考;} while (1);
}

【问题】

  • 若5位哲学家同时拿起筷子,则会发生死锁!

【解决】

  • 至多允许4位哲学家同时进餐:设置一个信号量semaphore count = 4控制最多只允许4位同时进餐
semaphore chopstick[5] = {11111};  //初始化为1
semaphore count = 4;
Pi()  //第i位哲学家结构
{
	do {
		wait(count);  //判断是否超过四个人进餐
		wait(chopstick[i]);  //取左筷子i
		wait(chopstick[(i + 1) % 5]);  //因为是圆桌,若i=0则i的右手边为第5根筷子
		…
		吃饭;signal(chopstick[i]);
		signal(chopstick[(i + 1) % 5]);
		signal(count);  //用餐完毕释放资源
		…
		思考;} while (1);
}
  • 对哲学家进行编号:奇数先拿左边再拿右边,偶数先拿右边在拿左边(若相邻哲学家同时拿起,则必有一方阻塞)
semaphore chopstick[5] = {11111}  //初始化为1

Pi()  //第i位哲学家结构
{
	do {
		if(i%2 == 1)  //奇数号
		{
			wait(chopstick[i]);  //取左筷子i
			wait(chopstick[(i + 1) % 5]);  //因为是圆桌,若i=0则i的右手边为第5根筷子
		}
		else  //偶数号
		{
			wait(chopstick[i+1]%5);  //取右
			wait(chopstick[i]);  //取左
		}
		…
		吃饭;signal(chopstick[i]);
		signal(chopstick[(i + 1) % 5]);
		…
		思考;} while (1);
}

四、练习

1.水果问题

桌上有一个盘子,可以放一个水果;
父亲总是放苹果到盘子中;
母亲总是放香蕉到盘子中。
一个儿子专等吃盘中的香蕉;
而一个女儿专等吃盘中的苹果。
父母只放水果不吃,儿女只吃水果不放。
实现父亲,母亲,儿子,女儿的进程同步。
用PV操作实现下述问题的解

2.和尚打水问题

某寺庙,有小,老和尚若干,有一个水缸,有小和尚打水入缸供老和尚取水饮用。
水缸可以放10桶水。水桶总数为3个。
每次入、取缸水只能是1桶,且不可以同时进行。
小和尚从一个井里面打水。水井狭窄,每次只能容纳一个桶取水。
试用信号量和P,V操作给出小和尚打水入缸和老和尚从缸里取水的算法描述

3.餐厅职员问题

一个快餐厅有4类职员:
(1)领班:接受顾客点菜,出菜单;
(2)厨师:根据菜单,准备顾客的饭菜;
(3)打包工:将做好的饭菜打包;
(4)出纳员:收款并提交食品。
每个职员可被看作一个进程,试用一种同步机制写出能让四类职员正确并发运行的程序。

4.汽车站点问题

在公共汽车上,司机和售票员的活动分别是:
司机的活动:启动车辆,正常行车,到站停车。
售票员的活动:上下乘客,关车门,售票,开车门,上下乘客。
在汽车不停的到站,停站,行驶过程中,这两个活动有什么同步关系?用信号量和P,V操作实现它们的同步。

5.进程流图问题

假设有一个作业由四个进程组成,这四个进程在运行时必须按如图所示的次序依次执行,试用P,V原语表达四个进程的同步关系。
在这里插入图片描述

6.观察者-报告者问题

用P,V操作实现下述问题的解:
观察者和报告者是两个并发执行的进程,观察者不断观察并对通过的卡车计数,报告者定时的将观察者的计数值打印,打印完毕,将计数值清零。

7.阅览室问题

假定阅览室最多可同时容纳100个人阅读,读者进入时,必须在阅览室门口的一个登记表上登记,内容包括姓名、座号等,离开时要撤掉登记内容。
用P、V操作描述读者进程的同步算法

  • 22
    点赞
  • 225
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

憨憨憨羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值