操作系统PV操作题整理1

1 餐厅分为等待区、用餐区、厨房。等待区中有n个椅子,顾客来了有位置则坐下,没有就离开。厨房互斥使用,进入厨房后椅子后椅子空出来供顾客坐下。用餐处有m个位置,用完厨房看用餐处是否有空位,如果有空位则顾客从厨房出来并叫清洁员A清扫,没有则坐在厨房等待。顾客到用餐处用餐后,通知清洁员B进行打扫。

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}


void Student(int *kitchen,int *seats,int *desks,int *cleaner_A,int *cleaner_B)
{
	while(1)
	{
		printf("Student process\n");
		P(seats);
		P(kitchen);  //等待厨房
		printf("enter kitchen...\n");
		V(seats);  //离开椅子
		P(desks);  //等待用餐桌
		V(cleaner_A);  //可以打扫厨房
		printf("eating...\n");
		V(cleaner_B);  //可以打扫餐桌
		getch();
	}
}

void Cleaner_A(int *cleaner_A,int *kitchen)
{
	while(1)
	{
		printf("Cleaner_A process\n");
		printf("having break...\n");
		P(cleaner_A); //等待打扫
		printf("cleaning...\n");
		V(kitchen); //离开厨房
		getch();
	}
}

void Cleaner_B(int *cleaner_B,int *desks)
{
	while(1)
	{
		printf("Cleaner_B process\n");
		printf("having break...\n");
		P(cleaner_B); //等待打扫
		printf("cleaning...");
		V(desks); //离开餐桌
		getch();
	}
}

int main()
{
	int n=4,m=3;
	semaphore seats=n,desks=m,kitchen=1,cleaner_A=0,cleaner_B=0;
	Student(&kitchen,&seats,&desks,&cleaner_A,&cleaner_B);
	Cleaner_A(&cleaner_A,&kitchen);
	Cleaner_B(&cleaner_B,&desks);
	return 0;
}

2.订票与查票,可多个查票,订票者与查票者不可同时操作且按请求顺序提供服务

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}


void Order(int *w,int *rw)
{
	while(1)
	{
		P(w);//在无查询者时可以进入
		P(rw);//互斥访问系统
		printf("Order ticket...\n");
		V(rw); //释放系统访问
		V(w);  //表示查询者可以访问
		getch();
	}
}

void Check(int *w,int *rw,int *mutex,int *count)
{
	while(1)
	{
		P(w);
		P(mutex);
		if(count==0) //当第一个查询者进入系统时
			P(rw); //阻止订票者订票
		count++;
		V(mutex);
		V(w);
		printf("checking...\n");
		P(mutex);
		count--;
		if(count==0)
			V(rw);
		V(mutex);
		getch();
	}
}

int main()
{
	int count=0;//用于记录当前的查询者数量
	semaphore mutex=1; //用于对count变量的互斥访问
	semaphore rw=1; //用于保证查询者和订票者互斥访问系统
	semaphore w=1; //用于保证查询者和订票者都不优先
	Order(&w,&rw);
	Check(&w,&rw,&mutex,&count);
	return 0;
}

3.一个果盘可以放两个水果,父亲放苹果,母亲放橘子,女儿取水果。要求只有一个人可以操作果盘,只有果盘里同时有苹果和橘子时,女儿才可以取水果,并且同时把两个水果取走。 这个程序有问题会造成死锁,解决方法是采取同步机制,dad放完苹果后要释放mutex信号量,然后要等到果盘空了才能继续放,mom要等到apple信号量才能放,释放apple,释放mutex,女儿进程没有问题,所以应当再增加一个信号量来解决同步问题

#include<stdio.h>
#include<conio.h>
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}



void dad(int *empty,int *apple,int *mutex)
{
	printf("dad process\n");
	while(1)
	{
		printf("prepare an apple...\n");
		P(empty);
		P(mutex);
		printf("put an apple...\n");
		V(apple);
		getch();
	}
}

void mom(int *empty,int *mutex,int *orange)
{
	printf("mom process\n");
	while(1)
	{
		printf("prepare an orange...\n");
		P(empty);
		P(mutex);
		printf("put an orange...\n");
		V(orange);
		getch();
	}
}

void daughter(int *apple,int *orange,int *empty,int *mutex)
{
	printf("duaghter process\n");
	while(1)
	{
		P(apple);
		P(orange);
		P(mutex);
		printf("take fruits...\n");
		V(mutex);
		V(empty);
		V(empty);
		getch();
	}
}

int main()
{
	semaphore mutex=1,apple=0,orange=0,empty=2;
	dad(&empty,&apple,&mutex);
	mom(&empty,&mutex,&orange);
	daughter(&apple,&orange,&empty,&mutex);
	return 0;
}

4.N个生产者进程和M个消费者进程共享大小为K的缓冲区,规则如下,进程之间互斥访问缓冲区,对每条放入缓冲区的数据,所有消费者必须接受一次,缓冲区满时,生产者必须阻塞,缓冲区空时,消费者必须阻塞。

#include<stdio.h>
#include<conio.h>

#define M 10
#define k 5
typedef int semaphore;

struct process
{
	
};

typedef struct
{
	int value;         //资源个数
	struct process *L;
}ss;

void P(int *n)
{
	(*n)--;   //申请一个资源
	printf("apply a resource! n=%d\n",(*n));
	if((*n)<0)printf("no resources available,block the process!\n");
}

void V(int *n)
{
	(*n)++;   //释放一个资源
	printf("release a resource! n=%d\n",(*n));
	if((*n)<=0)printf("still another process is blocked, wakeup one from the block queue.\n");
}


void producer(int *empty,int *mutex,int *full)
{
	int i;
	while(1)
	{
		for(i=1;i<M;i++)
			P(&empty[i]);
		P(mutex);
		printf("put data...\n");
		V(mutex);
		for(i=1;i<=M;i++)
			V(&full[i]);
		getch();
	}
}


void consumer(int *mutex,int *full,int *empty)
{
	int i;
	while(1)
	{
		P(&full[i]);
		P(mutex);
		printf("take out data...\n");
		V(mutex);
		V(&empty[i]);
		getch();
	}
}


int main()
{
	semaphore mutex=1;
	semaphore empty[M]={k};
	semaphore full[M]={0};
	producer(empty,&mutex,full);
	consumer(&mutex,full,empty);
	return 0;
}
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验目: 生产者与消费者(综合性实验) 实验环境: C语言编译器 实验内容: ① 由用户指定要产生的进程及其类别,存入进入就绪队列。    ② 调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源被阻塞则进入相应的等待队列,调度程序调度就绪队列中的下一个进程。进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。运行结束的进程进入over链表。重复这一过程直至就绪队列为空。    ③ 程序询问是否要继续?如果要转直①开始执行,否则退出程序。 实验目的: 通过实验模拟生产者与消费者之间的关系,了解并掌握他们之间的关系及其原理。由此增加对进程同步的问的了解。 实验要求: 每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态、进程产品(字符)、进程链指针等等。 系统开辟了一个缓冲区,大小由buffersize指定。 程序中有三个链队列,一个链表。一个就绪队列(ready),两个等待队列:生产者等待队列(producer);消费者队列(consumer)。一个链表(over),用于收集已经运行结束的进程 本程序通过函数模拟信号量的操作。 参考书目: 1)徐甲同等编,计算机操作系统教程,西安电子科技大学出版社 2)Andrew S. Tanenbaum著,陈向群,马红兵译. 现代操作系统(第2版). 机械工业出版社 3)Abranham Silberschatz, Peter Baer Galvin, Greg Gagne著. 郑扣根译. 操作系统概念(第2版). 高等教育出版社 4)张尧学编著. 计算机操作系统教程(第2版)习解答与实验指导. 清华大学出版社 实验报告要求: (1) 每位同学交一份电子版本的实验报告,上传到202.204.125.21服务器中。 (2) 文件名格式为班级、学号加上个人姓名,例如: 电子04-1-040824101**.doc   表示电子04-1班学号为040824101号的**同学的实验报告。 (3) 实验报告内容的开始要列出实验的目的,实验环境、实验内容等的说明,报告中要附上程序代码,并对实验过程进行说明。 基本数据结构: PCB* readyhead=NULL, * readytail=NULL; // 就绪队列 PCB* consumerhead=NULL, * consumertail=NULL; // 消费者队列 PCB* producerhead=NULL, * producertail=NULL; // 生产者队列 over=(PCB*)malloc(sizeof(PCB)); // over链表 int productnum=0; //产品数量 int full=0, empty=buffersize; // semaphore char buffer[buffersize]; // 缓冲区 int bufferpoint=0; // 缓冲区指针 struct pcb { /* 定义进程控制块PCB */ int flag; // flag=1 denote producer; flag=2 denote consumer; int numlabel; char product; char state; struct pcb * processlink; …… }; processproc( )--- 给PCB分配内存。产生相应的的进程:输入1为生产者进程;输入2为消费者进程,并把这些进程放入就绪队列中。 waitempty( )--- 如果缓冲区满,该进程进入生产者等待队列;linkqueue(exe,&producertail); // 把就绪队列里的进程放入生产者队列的尾部 void signalempty() bool waitfull() void signalfull() void producerrun() void comsuerrun() void main() { processproc(); element=hasElement(readyhead); while(element){ exe=getq(readyhead,&readytail); printf("进程%d申请运行,它是一个",exe->numlabel); exe->flag==1? printf("生产者\n"):printf("消费者\n"); if(exe->flag==1) producerrun();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值