• 大小: 312KB
    文件类型: .rar
    金币: 1
    下载: 0 次
    发布日期: 2021-06-13
  • 语言: C/C++
  • 标签:

资源简介

实验题目: 生产者与消费者(综合性实验) 实验环境: 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();

资源截图

代码片段和文件信息

/*

*/
#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

 属性            大小     日期    时间   名称
----------- ---------  ---------- -----  ----

     文件      41984  2008-12-27 14:55  sy2\Debug\vc60.idb

     文件      61440  2008-12-27 14:55  sy2\Debug\vc60.pdb

     文件     259284  2008-12-27 14:55  sy2\Debug\sy2.ilk

     文件     217192  2008-12-27 14:55  sy2\Debug\sy2.exe

     文件     525312  2008-12-27 14:55  sy2\Debug\sy2.pdb

     文件          0  2008-12-27 14:55  sy2\Debug\sy2.sbr

     文件     263384  2008-12-27 14:55  sy2\Debug\sy2.pch

     文件      17532  2008-12-27 14:55  sy2\Debug\sy2.obj

     文件      74752  2008-12-27 14:55  sy2\Debug\sy2.bsc

     文件      41984  2008-12-27 15:06  sy2\sy2.ncb

     文件        869  2008-12-27 14:55  sy2\sy2.plg

     文件       3369  2008-12-27 14:50  sy2\sy2.dsp

     文件        531  2008-12-27 14:50  sy2\sy2.dsw

     文件      48640  2008-12-27 15:06  sy2\sy2.opt

     文件       5023  2009-01-07 20:35  sy2\sy2.cpp

     文件      94208  2009-01-07 20:35  实验报告2.doc

     目录          0  2008-12-27 12:23  sy2\Debug

     目录          0  2008-12-24 08:28  sy2

----------- ---------  ---------- -----  ----

              1655504                    18


评论

共有 条评论