资源简介
这个是很经典的问题
实验题目: 生产者与消费者(综合性实验)
实验环境: 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();
else
comsuerrun();
element=hasElement(readyhead);
}
printf("就绪队列没有进程\n");
if(ha
代码片段和文件信息
/*
*/
#include
#include
#include
struct PCB
{
int flag; //1为生产者2为消费者
int numLabel;
};
typedef struct QNode
{
PCB data;//数据域
struct QNode* next;//指针域
}QNode *QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}linkQueue;
typedef struct LNode
{
QueuePtr data;
struct LNode *next;
}LNode *linkList;
void QueueInit(linkQueue& Q)//初始化队列
{
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
Q.front->next = NULL;
}
void linkListInit(linkList& L)//初始化链表
{
L = (linkList)malloc(sizeof(LNode));
}
void EnQueue(linkQueue& Q QueuePtr p)//入队
{
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
}
QueuePtr DeQueue(linkQueue& Q)//出队
{
QueuePtr p = Q.front->next;
Q.front->next = p->next;
if(Q.rear == p)Q.rear =Q.front;
return p;
}
void linkListInsert(linkList& L QueuePtr e)//进入链表
{
linkList p = L;
linkList q = (linkList)malloc(sizeof(LNode));
while(p->next)p++;
q->data = e;
q->next = NULL;
p->next = q;
}
void processproc(linkQueue& Q)//创建进程进入初始队列
{
int processNum = 0;
cout<<“请输入进程的个数:“;//确定进程个数,默认为0
cin>>processNum;
for(int i = 0; i < processNum; i++)
{
cout<<“输入第“< struct PCB pcb;
cin>>pcb.flag;//输入进程的种类
pcb.numLabel = i+1;//进程序号赋值
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
p->data = pcb;
EnQueue(Q p);
}
}
bool HasElement(linkQueue Q)//判断队列是否为空
{
if(Q.front == Q.rear)return false;
else return true;
}
int ProduceRun(int& full int BufferSize)//运行生产者进程
{
if(full < BufferSize)
{
full++;
return 1;
}
return 0;
}
int ConsumeRun(int& full int BufferSize)//运行消费者进程
{
if(full > 0)
{
full--;
return 1;
}
return 0;
}
void DisPlay(linkQueue Q)//打印队列
{
QueuePtr p = Q.front;
while(p->next){
cout<<“进程“<next->data.numLabel< p = p->next;
}
}
void main()
{
int BufferSize;//设置缓冲区大小
cout<<“请设置缓冲区的大小: “;
cin>>BufferSize;
int full = 0;//当前缓冲区中的进程数目
int temp = 1;
linkList over;//用于收集已经运行结束的进程
linkListInit(over);
linkQueue ReadyQueue;//就绪队列
linkQueue ProducerWaitQueue;//生产者等待队列
linkQueue ConsumerWaitQueue;//消费者等待队列
//初始化
QueueInit(ReadyQueue);
QueueInit(ProducerWaitQueue);
QueueInit(ConsumerWaitQueue);
while(temp)//死循环
{
processproc(ReadyQueue);//创建进程进入就绪队列
bool element=HasElement(ReadyQueue);//判断队列是否为空
while(element)//当它不是空的
{
cout<<“进程“<next->data.numLabel<<“申请运行他是一个“;
/********************************************************************/
if(ReadyQueue.front->next->data.flag == 1)//如果它是一个生产者
{
cout<<“生产者“<
if(ProduceRun(full BufferSize) == 1)//判断缓存区是否还有空间
{
cout<<“进程“<next->data.numLabel<<“执行完毕“< linkListInsert(over DeQueue(ReadyQueue));//运行结束,进入over链表
if(HasElement(ProducerWaitQueue))//检查生产者等待队列,激活队列中的进程进入就绪队列
EnQueu
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 5023 2009-01-07 20:35 sys2\sy2\sy2.cpp
文件 94208 2009-01-07 20:35 sys2\实验报告2.doc
目录 0 2011-06-12 08:54 sys2\sy2
目录 0 2011-06-12 08:52 sys2
----------- --------- ---------- ----- ----
99231 4
评论
共有 条评论