操作系统PV操作的几个例子

本文通过四个具体的案例展示了操作系统中PV操作如何实现进程间的同步,包括顾客与销售人员的同步、三个进程对数据的顺序处理、读者写者问题的写优先方案及双向单通桥上的车辆通行控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

操作系统中PV操作的几个例子


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


思路:顾客进店后按序取号,并等待叫号,销售人员空闲之后也是按序叫号,并销售面包。因此同步算法只要对顾客取号和销售人员叫号进行合理的同步即可。我们使用两个变量i和j分别记录当前的取号值和叫号值,并各自使用一个互斥信号用于对i和j的访问和修改


代码:
int i=0,j=0;
semaphore mutex_i=1,mutex_j=1;
Consumer()
{
	//进入面包店
	p(mutex_i);
	//取号i
	i++;
	v(mutex_i);
	//等待叫号i并购买面包
}


Seller()
{
	while(1)
	{
		p(mutex_j);
		if(j<i) //号j已有顾客取走并等待
		{
			//叫号j
			j++;
			v(mutex_j);
			//销售面包
		}
		else
		{
			v(mutex_j);
			//休息片刻
		}
	}
}





题2:三个合作进程P1,P2,P3,它们都需要通过同一设备输入各自的数据a,b,c,该输入设备必须互斥地使用,而且其第一个数据必须有P1进程读取,第二个数据必须由P2进程读取,第三个数据必须由P3进程读取。然后三个进程分别对输入数据进行下列计算:
P1:x=a+b;
P2:y=a*b;
P3:z=y+c-a;
最后P1进程通过所连的打印机将结果x,y,z的值打印出来,请用信号量实现他们同步。


思路:为了控制三个进程依次使用输入设备进行输入,需分别设置三个信号量S1,S2,S3,其中S1初值为1,S2和S3初值为0.使用上述信号量后,三个进程不会同时使用输入设备,故不必再为输入设备设置互斥信号量。另外,还需要设置信号量Sb,Sy,Sz来表示数据b是否已经输入,以及y,z是否已经计算完成,他们的初值均为0。


代码:
P1()
{
	P(S1);
	//从输入设备输入数据a
	V(S2);
	P(Sb);
	x=a+b;
	P(Sy);
	P(Sz);
	//使用打印机打印出x,y,z的结果
}


P2()
{
	P(S2);
	//从输入设备输入数据b
	V(S3);
	V(Sb);
	y=a*b;
	V(Sy);
	V(Sy);
}


P3()
{
	P(S3);
	//从输入设备输入数据c
	P(Sy);
	z=y+c-a;
	V(Sz);
}







题3:在读者写者问题中,允许多个读者同时读数据,但不允许写者与其他写者进程同时访问数据。另外要保证:一旦有写者等待,新到达的读者必须等待,知道该写者完成数据访问为止,用PV操作实现。


思路:这是一个“写优先”的读者-写者问题,在经典的“读优先”的读者-写者文章的PV操作中,只要再添加一个信号量w=1,用以在写进程到达时封锁后续进程,即可实现“写优先”


代码:
int count=1;//记录当前读者数量
semaphore mutex=1;//保护更新count变量时的互斥
semaphore rw=1;//保证读者和写者互斥地访问文件
semaphore w=1;//实现“写优先”


writer()
{
	while(1)
	{
		P(w);
		P(rw);
		//writing
		V(rw);
		V(w);
	}
}




reader()
{
	while(1)
	{
		P(w);
		P(mutex);
		if(count==0)
		{
			P(rw);
		}
		count++;
		V(mutex);
		V(w);
		//reading
		P(mutex);
		count--;
		if(count==0)
		{
			V(rw);
		}
		V(mutex);
	}
}







题4:有桥如图,车流方向如箭头所示,假设该桥上不允许两车交会,但允许同方向多个车一次通过(桥上可有多个同方向行驶的车),试用信号量PV实现




代码:
int countSN=0;//表示从南到北的汽车数量
int countNS=0;//表示从北到南的汽车数量
semaphore mutexSN=1;//保护countSN
semaphore mutexNS=1;//保护countNS
semaphore bridge=1;//互斥访问桥


StoN()
{
	p(mutexSN);
	if(countSN==0)
	{
		p(bridge);
	}
	countSN++;
	v(mutexSN);
	//过桥
	p(mutexSN);
	countSN--;
	if(countSN==0)
	{
		v(bridge);
	}
	v(mutexSN);
}


NtoS()
{
	p(mutexNS);
	if(countNS==0)
	{
		p(bridge);
	}
	countNS++;
	v(mutexNS);
	//过桥
	p(mutexNS);
	countNS--;
	if(countNS==0)
	{
		v(bridge);
	}
	v(mutexNS);
	
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值