如何使用信号量处理问题

本文通过分析7个并发问题,如生产者-消费者、哲学家进餐、理发师睡眠等,阐述如何利用信号量进行同步和互斥操作。详细讨论了信号量的赋值、P、V操作的意义,以及在解决问题时如何确定互斥量、进程间关系和资源申请顺序,以避免死锁和饥饿现象。
摘要由CSDN通过智能技术生成

从信号量的理论跨越到对其应用解决实际的问题,对于我这种人来说,是一种脱离地心引力飞向太阳系的体验。

以下有7个问题(不写目录了)。

1、

生产者---消费者问题

有一个或多个生产者生产某种类型的数据(记录、字符),并防止在缓冲区中;有一个消费者从缓冲区中取数据,每次取一项;系统保证避免对缓冲区的重复操作,也就是说,在任何时候只有一个主体(生产者或者消费者)可以访问缓冲区。问题是要确保这种情况,当缓冲区已满时,生产者不会继续向其中添加数据;当缓冲区为空时,消费者不会从中移走数据。

1)问题分析:

从题中可以发现需要对缓冲区进行同步互斥操作,生产者为消费者生产必要产品放入缓冲区,消费者为生产者生产空闲缓冲区,这就需要同步操作;对于同一个缓冲区而言,只能有一个生产者或消费者访问,也就是生产者与生产者之间、生产者与消费者、消费者与消费者需要互斥操作。

对于生产者:

判断缓冲区是否为满,如果为满,则等待;否则,允许一个生产者写入。

对于消费者:

判断缓冲区是否为空,如果为空,则等待;否则,允许一个消费者读取。

2)伪码描述:

semaphore buffer, empty, full;//分别表示缓冲,缓冲剩余资源,缓冲已用资源的信号量
buffer.v = 1;//表示缓冲空闲
empty.v = MAX_SIZE;//表示缓冲为空
full.v = 0;//表示缓冲为空
void Producer()
{
	while(isProduce()) {
		//produce	
		P(empty);//判断是否有空闲的缓冲
		P(buffer);//判断缓冲是否占用
		append();//将产品放入缓冲中
		V(buffer);//释放对缓冲的使用
		V(full);//缓冲中添加一块产品
	}
}
void Consumer()
{
	while(isConsume()) {
		P(full);//判断是否有非空的缓冲
		P(buffer);//判断缓冲是否占用
		take();//取走产品
		V(buffer);//释放对缓冲的使用
		V(empty);//多出一块空闲缓冲区
		//consume
	}
}

2、

哲学家进餐问题

有5位哲学家住在一座房子里,在他们面前有一张餐桌。每位哲学家的生活就是思考和吃饭。所有的哲学家的食物是意大利面条,由于缺乏手工技能,每位哲学家需要两把叉子进餐。一个圆盘上有一大碗面,每位哲学家面前有一个盘子,左手边有一个叉子。每个想吃饭的哲学家将坐到桌子旁分配给他的位置上,使用盘子两侧的叉子,取面和吃面。

1)问题分析:

题中的叉子显然是一个互斥资源,对于一个叉子而言,如果有一个哲学家占用,那么另一个哲学家只能等待。

对于每一个哲学家来说,

他需要判断能否申请到手边的两个叉子,如果只能得到一个或者没有得到叉子,只能等待;否则,可以进餐。

考虑到会出现饥饿的现象,比如:同时拿起左手边的叉子,所有哲学家同时等待。

为了解决这个问题,可以使用一个信号量表示餐桌上最多坐四人,第5位哲学家想坐时,只能等待。

2)伪码描述:

semaphore forkLeft, forkRight, people;//左手边的叉子,右手边的叉子,允许使用桌子的人数
forkLeft.v = forkRight.v = 1;//表示两手边的叉子都处于空闲
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值