PV操作题型整理

欢迎各路大佬指正!

基础

在这里插入图片描述
在这里插入图片描述

生产者消费者问题

void p1(){
 while(1){
	生产一个产品;
	P(empty);
	P(mutex);
	把产品放入缓冲区;
	V(mutex);
	V(full);
	}
}

void p2()
{
while(1)
 {
	P(full);
	P(mutex);
	消费一个产品;
	V(mutex);
	V(empty);
	}
}

多生产者消费者问题(父母与两个孩子与水果的问题)

semaphore mutex=1;
semapgore plate=1;
semaphore apple=0;
semaphore orange=0;


void father(){//---爸爸生产apple
	while(1)
	{
		准备苹果;
		P(plate);
		P(mutex);
		把苹果放入盘子;
		V(mutex);
		V(apple);
	}

}

void mather(){
	while(1){
		准备橘子;
		P(plate);
		P(mutex);
		把橘子放入盘子;
		V(mutex);
		V(orange);
	}
}

void daughter()
{
	while(1){
		P(apple);
		P(mutex);
		拿走苹果;
		V(mutex);
		V(plate);
	}
}

void son(){
	while(1){
		P(orange);
		P(mutex);
		从盘子中拿走句子;
		V(mutex);
		V(plate);
	}
}

吸烟者问题

semaphore offer1=0;
semaphore offer2=0;
semaphore offer3=0
semaphore finish=0;
int i=0;

void provider(){
	while(1){
		if(i==0)
		{1放在桌子上;
			V(offer1);
		}
		else if(i==1)
		{
			2放在桌子上;
			V(offer2);
		}
		else if(i==2)
		{
			3放在桌子上;
			V(offer3);
		}
		i=(i+1)%3;
		P(finish);
	}

}

void smoker1()
{
	while(1)
	{
		P(offer1);
		拿走1V(finish);
	}
}
void smoker2()
{
	while(1)
	{
		P(offer2);
		拿走2V(finish);
	}
}
void smoker3()
{
	while(1)
	{
		P(offer3);
		拿走3V(finish);
	}
}

读-写者问题

互斥关系:写-写;读-写;

semaphore mutex=1;
semaphore rw=1;//是否存在共享文件
semaphore w=1;//写优先
int count=0;

void writer(){
	while(1)
	{
		P(w);
		P(rw);
		写文件;
		V(rw);
		V(w);
	}

}

void reader(){
	while(1)
	{
		P(w);
		P(mutex);
		if(count==0)
		{
			P(rw);
		}
		count++;
		V(mutex);
		V(w);
		读文件;
		P(mutex);
		count--;
		if(count==0)
		{
			V(rw);
		}
		V(mutex);

	}
}

哲学家进餐

(5个哲学家)

semaphore mutex=1;
semaphore chopstick[5]={1,1,1,1,1}

void Pi(){
	while(1)
	{
		P(mutex);
		P(chopstick[i]);//左
		P(chopstick[(i+1)%5]);//右
		V(mutex);
		吃饭;
		V(chopstick[i]);
		V(chopstick[(i+1)%5]);
		思考;
	}
}

阅览室

1、有一阅览室,共有100个座位。读者进入时必须先在一种登记表上登记,该表为每一座位列一个表目,包括座号和读者姓名。读者离开时要注销掉登记内容。试用wait和signal原语描述读者进程的同步问题。

semaphore empty=100;
semaphore full=0;
semaphore mutex=1;
void add_name();
void del_name();

void Stu()
{
	while(1)
	{
		P(empty);
		P(mutex);
		add_name();
		坐下;
		V(mutex);
		阅读;
		P(mutex);
		del_name();
		V(mutex);
		V(empty);

	}
}


南开到天大的小路

在这里插入图片描述

semaphore M=2;
semaphore k=1;
semaphore l=1;


void N_T()
{
	while(1){
		P(M);
		P(k);
		N到M;
		V(k);

		P(l);
		V(M);
		M到T;
		V(l);

	}
}

void T_N(){
	while(1)
	{
		P(M);
		P(l);
		T到M;
		V(l);

		P(k);
		V(M);
		M到T;
		V(k);
	}
}

司机售票员问题

司机:启动->正常行车->到站停车;
售票员:关车门->售票->开车门;
停车后才能开车门,关车门才能行车;

semaphore car=1;
semaphore door=0;


void driver(){
	while(1){
		P(car);//---请求启动汽车;
		启动车辆;
		正常行车;
		到站停车;
		V(door);//释放开门变量
	}
}

void ticketseller()
{
	while(1)
	{
		关车门;
		V(car);//--释放可以开车信号
		售票;
		P(door);//--请求开门;
		开车门;
		乘客上下车;

	}
}

图书馆占座问题

在这里插入图片描述

semaphore seat=100;
semaphore mutex=1;

void P1()
{
	while(1)
	{
		P(seat);
		P(mutex);
		登记;
		V(mutex);
		入座;
		P(mutex);
		注销;
		V(mutex);
		V(seat);
	}
}

int count=100;
void P1(){
	while(1)
	{
		P(mutex);
		if(count==0)
		{
			回家;
			V(mutex);
		}
		else
		{
			count--;
			登记;
			V(mutex);
			入座;
			P(mutex);
			count++;
			V(mutex);
			回家;
		}


	}
}

独木桥

在这里插入图片描述
1.

semaphore mutex=1;
void P1()
{
	while(1)
	{
		P(mutex);
		过桥;
		V(mutex);
	}
}

2。

semaphore mutex1=1;
semaphore mutex2=1;
semaphore wait=1;
int count_1=0;
int count_2=0;



void P2()
{
	while(1)
	{
		P(mutex1);
		count_1++;
		if(count_1==1)
		{
			P(wait);
		}
		V(mutex1);
		过独木桥;

		P(mutex1);
		count_1--;
		if(count_1==0)
		{
			V(wait);
		}
		V(mutex1);
	}
}

void P2(){
	while(1){
		P(mutex2);
		count_2++;
		if(count_2==1)
		{
			P(wait);
		}
		V(mutex2);
		过桥;
		P(mutex2);
		count_2--;
		if(count_2==0)
		{
			V(wait);
		}
		V(mutex2);
	}
}
void P1()
{
	while(1)
	{
		P(mutex);
		过桥;
		V(mutex);
	}
}
void P2()
{
	while(1)
	{
		P(mutex1);
		count_1++;
		if(count_1==1)
		{
			P(wait);
		}
		V(mutex1);
		过独木桥;

		P(mutex1);
		count_1--;
		if(count_1==0)
		{
			V(wait);
		}
		V(mutex1);
	}
}

理发师睡觉

在这里插入图片描述

int seat=n;
int waiting=0;//等待理发师的顾客数
semaphore barber=0;
semaphore customer=0;
semaphore mutex=1;

void barber()
{
	while(1){
		P(customer);//---没有顾客睡觉;
		P(mutex);
		waiting--;
		V(barber);//---理发师去理发;
		V(mutex);//释放信号量
		理发;
		
	}
}

void customer()
{
	while(1){
		P(mutex);
		if(waiting)
		{
			waiting++;
			V(customer);//唤醒理发师
			V(mutex);
			P(barber);//没有理发师时,顾客坐着
			坐下等待理发;
		}
		else{
			V(mutex);//人太多了走了
		}

	}
}

另一种解法:



int custNum=0;
semaphore wait=0;//等待顾客数
semaphore barber=0;
semaphore mutex=1;

void Customer(){
	while(1)
	{
		顾客来到;
		if(custNum>1){
			if(customer<=N)//有顾客并且小于等于座位数
			{
				V(mutex);
				P(wait);
			}
			else{
				V(mutex);
				离开;
			}
		}
		else
		{
			V(mutex);
			V(barber);
			理发;
			离开;
			P(mutex);
			custNum--;
			V(mutex);
			V(wait);
		}
	}
}


void Barber(){
	while(1)
	{
		P(mutex);
		if(custNum==0)
		{
			V(mutex);
			P(barber);//睡觉等待;
		}
		else
		{
			V(mutex);
			理发;
		}
	}
}

王道:

semaphore customers=0;
semaphore barber=0;
semaphore mutex=1;
int chairs=n;
int waiting=0;

void Barber(){
	while(1){
		P(customers); //若无顾客则睡觉;
		P(mutex);
		waiting--;
		V(barber);//一个理发师去理发;
		V(mutex);
		理发;
	}
}

void Customer(){
	while(1){
		if(waiting<chairs){
			waiting++;
			V(customers);//等待顾客+1
			V(mutex);
			P(barber);//若无理发时,则坐下休息
			坐下等待理发;
		}
		else{
			mutex;//人满,离开
		}
	}

}

和尚打水问题

某寺庙,有小和尚和老和尚若干,有一个水缸,由小和尚提水入缸供老和尚饮用.水缸可以容纳10桶水,水取自同一口井中,由于水井口窄,每次只能容纳一个水桶取水.水桶总数为3个。每次入水、取水仅为一桶,且不可同时进行。

semaphore well=1;//互斥访问井
semaphore vat=1;//互斥访问水缸
semaphore empty=10;//水缸剩余空间桶数
semaphore full=0;//水缸中水的桶数
semaphore pail=3;//表示还有多少桶水可以用

void old(){
	while(1)
	{
		P(pail);
		P(empty);
		P(vat);
		从水缸中取一桶水;
		V(vat);
		V(full);
		喝水;
		V(pail);
	}
}

void young(){
	while(1){
		
		P(pail);
		P(well);
		P(empty);

		从井中打一桶水;

		V(well);
		P(vat);
		倒入井中;
		V(vat);
		V(full);
		V(pail);//归还水桶
	}
}

仓库问题

A,B两种货物,每次当一种,满足A-B<M; B-A<N;

semaphore Ra=M-1;
semaphore Rb=N-1;
semaphore mutex=1;

void PA(){
	while(1){
		P(Ra);
		P(mutex);
		把A放入仓库;
		V(mutex);
		V(Rb);
	}
}

void PB()
{
	while(1){
		P(Rb);
		P(mutex);
		把B放入仓库;
		V(mutex);
		V(Ra);
	}
}

博物馆

最多容纳500人,有一个出入口,一次一人;参观者:进门->参观->出门。

semaphore mutex=1;
semaphore empty=500;

void Visitor()
{
	while(1)
	{
		...;
		P(empty);
		P(mutex);
		进门;
		V(mutex);
		参观;
		P(mutex);
		出门;
		V(mutex);
		V(empty);
		...;
	}
}

面包问题

面包师有很多面包,n名销售人员。每名顾客进店后取一个号,等待叫号,当一名销售人员空闲时,叫下一号。

semaphore mutex1=1;//g顾客取号
semaphore mutex2=1;//销售叫号
int i=0;
int j=0;

void customer()
{
	while(1)
	{
		进入面包店;
		P(mutex1);
		取号;
		i++;
		V(mutex1);
		等待叫号;
	}
}

void seller(){
	whie(1){
		P(mutex2);
		if(j<i)
		{
			叫号j;
			j++;
			V(mutex2);
			销售面包;
		}
		else{//暂时没有顾客等待
			V(mutex2);
		}
	}
}

配件车间

有A,B两个车间生产A,B。装配车间把A,B装配成成品,两个车间每生产出一件时、后,分别配送到货架F1,F2上。F1F2都可存放10件;工人每次从货架取一件A和一件B然后组装。

semaphore empty1=10;//货架1
semaphore empty2=10//货架2
semaphore full1=0;//货架上A数量
semaphore full2=0;//货架上B数量;
semaphore mutex1=1;//互斥访问F1
semaphore mutex2=1;//互斥访问F2

void A(){
	while(1){
		生产一件A;
		P(empty1);
		P(mutex1);
		把A放在货架F1;
		V(mutex1);
		V(full1);
	}
}

void B(){
	while(1){
		生产一件B;
		P(empty2);
		P(mutex2);
		把B放在F2上;
		V(mutex2);
		P(full2);
	}
}

void Prodece(){
	while(1){
		P(full1);
		P(mutex1);
		拿走一件A;
		V(mutex1);
		V(empty1);

		P(full2);
		P(mutex2);
		拿走一件B;
		V(mutex2);
		V(empty2);

		把AB组装成品;

	}
}

银行叫号

一个服务窗口,10个座位顾客等待,顾客:取号->等待->获取服务; 营业员:叫号->为客户服务;

semaphore empty=10;
semaphore mutex=1;//取号机
semaphore full=0;//已占座位数
semaphore service=0;//叫号
 void costumer(){
 	while(1){
 		P(empty);
 		P(mutex);
 		从取号机上取号;
 		V(mutex);
 		V(full);
 		P(service);
 		接受服务;
 	}
 }


 void clerk(){while(1){
 	P(full);
 	V(empty);
 	V(service);
 	为顾客服务;
 }}

箱子问题

生产线上有个箱子,N个位置(>=3),每个位置可存放一个车架或一个车轮,设有3名工人;工人1:加工一个车架->车界放入箱子中; 工人2:加工一个车轮->车轮入箱; 工人3:箱子中取出一个车架->取出一个车轮—>组合成一架车;

semaphore empty=10;
semaphore wheel=0;
semaphore frame=0;
semaphore s1=N-2;//车架max
semaphore s2=N-1;//车轮max

void P1(){
	while(1){
		加工一个车架;
		P(s1);
		车架入箱;
		P(empty);
		V(frame);
	}
}

void P2(){
	while(1)
	{
		加工一个车轮;
		P(s2);
		车轮入箱;
		P(empty);
		V(wheel);
	}
}

void P3(){
	while(1){
		拿出一个车架;
		P(frame);
		V(empty);
		V(s1);
		拿出两个车轮;
		P(wheel);
		P(wheel);
		V(empty);
		V(empty);
		V(s2);
		V(s2);
		组装成车;

	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值