操作系统——信号量的应用

生产者和消费者

在这里插入图片描述
有问题,一:存在忙等 二:多个生产者之间会存在问题

对生产者来说,==“资源”==是什么?
–空盒子数
–定义信号量empty,初始为n
–每次放入一个新产品时,需要wait(empty)

对消费者来说,==“资源”==是什么?
–产品数
–定义信号量 full,初始为0
–每次消耗一个产品时,需要wait(full)

生产者和消费者还需要做什么操作?
–生产者需要signal full
–消费者需要signal empty

在这里插入图片描述
当有多个生产者时,对buffer[in]=item, signal(full)这两句的操作如果交替运行会出问题,所以我们需要保证生产者对这两句的互斥访问。为此,添加mutex=1这样的信号量,在消费者的程序中同样需要处理这样的问题,所以也需要做相同处理。

作业一

题目:桌上有一空盘,只允许存放一个水果。爸爸专向盘中放橙子,妈妈专向盘中放苹果,女儿专等吃橙子,儿子专等吃苹果。规定当盘空时一次只能放一个水果供吃者自用,请用PV操作实现爸爸、妈妈、女儿、儿子四个并发进程的同步。

解:

设置信号量:semaphore: E=1, F1=0, F2=0
E表示盘中能放入的资源数
F1表示盘中的橙子数
F2表示盘中的苹果数

father()
{
	P(E);	 // 看盘子是否有可用空间	
	Put orange;
	V(F1); // 盘中橙子资源量+1	
}
mother()	
{
P(E); // 看盘子是否有可用空间
Put apple;
V(F2); // 盘中苹果资源量+1
}
daughter()
{
P(F1); // 看盘中是否有橙子
take orange; 
V(E); // 盘中可用空间 +1
}
son()
{		
P(F2); // 看盘中是否有苹果
take apple; 
V(E); // 盘中可用空间 +1
}

解释:爸爸和妈妈通过信号量E控制他们互斥访问并且只能放入一个,放入后,通过V(F1)/V(F2)的操作释放F1/F2的资源;对于女儿和儿子,通过F1和F2信号量使得daughter/son能够在盘中有对应他们要吃的东西时才去拿,并且由于盘中只能放入一个东西,所以也就同时实现了互斥访问。

作业二

题目:假设有个南北向的桥,仅能容同方向的人顺序走过,相对方向的两个人则无法通过。现在桥南北端都有过桥人。现把每个过桥人当成一个进程,用P,V操作实现管理。

解:

设置信号量:semaphore mutex=1, nmutex=1, smutex=1
mutex  实现互斥访问
nmutex 表示向北走的资源数
smutex 表示向南走的资源数
int north, south;
North()
{
	P(mutex); // 实现互斥进入
	P(nmutex); //查看是否可以向北走
	If(north == 0) 	P(smutex); // 向南走的资源数-1,阻塞
	north ++;
	V(nmutex);
	V(mutex);
	过桥
P(nmutex);
	north --;
	If(north == 0)	V(smutex); // 当桥上没有向北走的人时,释放向南走的资源
	V(nmutex);
}

South()
{
	P(mutex); // 实现互斥进入
	P(smutex); //查看是否可以向南走
	If(south == 0)	P(nmutex); // 向北走的资源数-1,阻塞
	south ++;
	V(smutex);
	V(mutex);
	过桥
P(smutex);
	south --;
	If(south == 0)	V(nmutex); 当桥上没有向南走的人时,释放向南走的资源
	V(smutex);
}

说明:一开始,南北向的进程竞争获得通过的权利,当有进程进入后,如果是第一个进入的,那么他会将对方的进程锁住,接下来如果后面进入的仍是同向的,则继续进入。当另一个方向的人获得了mutex资源,那么如果桥上还有人,他将会等待桥上的人走完,释放信号量后,就可以相应的进入了。

作业三

题目:读者写者同步问题中,解决写者饿死问题

Semaphore rmutex=1, wmutex=1, mutex=1;
Int readcount=0;
Void read()
{
	Do{
		P(mutex);
		P(rmutex);
		if(readcount==0)	P(wmutex);
		readcount ++;
		V(rmutex);
		P(mutex);
		…
		perform read operation;P(rmutex);
		readcount--;
		V(rmutex);
}while(tru);
}
void Writer()
{
	do{
		P(mutex);
		P(wmutex);
		perform write operation;
		signal(wmutex);
		P(mutex);
	}while(true);
}

解决方案:通过添加新的信号量mutex,保证writer和reader进程相对公平地竞争mutex信号量,这样只要writer获得信号量mutex,那么即使此时readcount!=0,新的reader进程也不可能进入,这样当期在读的进程读完后释放wmutex后,writer进程就可以执行了。

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值