您好,欢迎访问三七文档
广东海洋大学学生实验报告书(学生用表)实验名称缓冲池的模拟使用课程名称操作系统课程号学院(系)软件学院专业软件工程班级学生姓名学号实验地点实验日期一、实验目的(1)掌握缓冲池的结构(2)掌握缓冲池的使用方法二、实验内容1、实现输入、计算、输出进程并发执行;2、实现getBuf和putBuf函数。三、实验步骤1、整体设计,包括三个线程的模拟设计,三个队列的链表设计,还有三个队列的同步与互斥的设计等;2、由于本次实验没有需要太多的数据结构,因此,数据结构的设计就只有三个缓冲队列的设计:先构造一个空的缓冲队列,该队列是一个实体,即是一个确定的有结点的链表,它是模拟缓冲池的载体,输入与输出队列在构造时只有它的头尾指针,而没有它的实体,这是因为它可以从空缓冲区里获得,例如,当计算线程要数据计算时,便可从空队列里获取一个缓冲区,作为输入缓冲使用再把它挂载到输入队列的队尾中去实验内容如下://缓冲队列类型的定义#defineEMQ0//空缓冲队列#defineINQ1//输入缓冲队列#defineOUTQ2//输出缓冲队列constintbufferpoolsize=50;////缓冲池大小,默认设置为50个//结束运行标志shortintm_end;GDOU-B-11-112//缓冲结构体的定义typedefstructBuffer{intBufNo;//缓冲区号intbuf;//缓冲内容Buffer*next;//缓冲指向下一个指针}buffer;//线程函数声明DWORDWINAPIInputThreadFunc(LPVOIDlpPara);//输入线程函数DWORDWINAPIOutputThreadFunc(LPVOIDlpPara);//输出线程函数DWORDWINAPICalThreadFunc(LPVOIDlpPara);//计算线程函数//加入与摘取队列函数声明voidputBuf(inttype,buffer*buf);//挂载到队列尾buffer*getBuf(inttype);//从队列头中摘取一个缓冲区//构造缓冲池函数的声明voidConstructBuffer();//线程的句柄HANDLEhInputT;//输入线程HANDLEhOutputT;//输出线程HANDLEhCalculateT;//计算线程//线程的IDDWORDInputTid;//输入线程DWORDOutputTid;//输出线程DWORDCalculateTid;//计算线程//三个互斥量信号句柄HANDLEhmutexEMQ;//空队列的互斥信号量HANDLEhmutexOUTQ;//装满输出队列的互斥信号量HANDLEhmutexINQ;//装满输入队列的互斥信号量//三个同步信号量HANDLEhsemINQ;HANDLEhsemOUTQ;HANDLEhsemEMQ;#includewindows.h#includeiostream#includestdlib.h#includetime.h#includeMain1.husingnamespacestd;//三个缓冲队列头与尾指针buffer*hemq,*hinq,*houtq;//队头指针buffer*lemq,*linq,*loutq;//队尾指针//主函数intmain(){coutshow1endlshow2endlshow3endlendl;m_end=1;//运行结束标志ConstructBuffer();//构造缓冲池//创建互斥对象hmutexEMQ=CreateMutex(NULL,FALSE,NULL);hmutexOUTQ=CreateMutex(NULL,FALSE,NULL);hmutexINQ=CreateMutex(NULL,FALSE,NULL);//创建信号量对象hsemINQ=CreateSemaphore(NULL,0,bufferpoolsize,NULL);hsemOUTQ=CreateSemaphore(NULL,0,bufferpoolsize,NULL);hsemEMQ=CreateSemaphore(NULL,bufferpoolsize,bufferpoolsize,NULL);//创建线程hInputT=CreateThread(NULL,0,InputThreadFunc,NULL,0,&InputTid);Sleep(10);hCalculateT=CreateThread(NULL,0,CalThreadFunc,NULL,0,&CalculateTid);Sleep(10);hOutputT=CreateThread(NULL,0,OutputThreadFunc,NULL,0,&OutputTid);//Sleep(10000);//system(pause);if(getchar()){//按回车后终止程序运行m_end=0;cout程序已经终止!endl;}//等待三个线程的结束返回WaitForSingleObject(hInputT,INFINITE);WaitForSingleObject(hCalculateT,INFINITE);WaitForSingleObject(hOutputT,INFINITE);//释放线程的资源CloseHandle(hInputT);CloseHandle(hCalculateT);CloseHandle(hOutputT);return0;}//输入线程函数的实现DWORDWINAPIInputThreadFunc(LPVOIDlpPara)//输入线程函数{intnRandom;buffer*getbuf;srand(time(0));//保证每次运行时产生的随机数独立while(m_end){Sleep(100);nRandom=rand()%100+1;//产生1到100的随机数//同步与互斥的控制WaitForSingleObject(hsemEMQ,INFINITE);WaitForSingleObject(hmutexEMQ,INFINITE);getbuf=getBuf(EMQ);//访问空队列getbuf-buf=nRandom;cout输入线程从缓冲单元getbuf-BufNo---收容输入---data=getbuf-bufendl;ReleaseMutex(hmutexEMQ);//释放互斥对象信号//控制访问输入队列的互斥量WaitForSingleObject(hmutexINQ,INFINITE);putBuf(INQ,getbuf);//将输入的缓冲区挂载到输入队列的队尾ReleaseMutex(hmutexINQ);ReleaseSemaphore(hsemINQ,1,NULL);}return0;}//输出线程函数的实现DWORDWINAPIOutputThreadFunc(LPVOIDlpPara)//输出线程函数{buffer*Outputbuf;//一个临时交换区while(m_end){Sleep(100);////同步与互斥的控制WaitForSingleObject(hsemOUTQ,INFINITE);WaitForSingleObject(hmutexOUTQ,INFINITE);Outputbuf=getBuf(OUTQ);//从输出队列中提取一个提取输出缓冲区cout输出线程从缓冲单元Outputbuf-BufNo---提取输出---data=Outputbuf-bufendl;//Outputbuf-buf=-1;//提取完成后将该缓冲区回收ReleaseMutex(hmutexOUTQ);WaitForSingleObject(hmutexEMQ,INFINITE);putBuf(EMQ,Outputbuf);//回收的把它挂载到空队列的队尾ReleaseMutex(hmutexEMQ);ReleaseSemaphore(hsemEMQ,1,NULL);}return0;}//计算线程函数的实现DWORDWINAPICalThreadFunc(LPVOIDlpPara)//计算线程函数{buffer*Calbuf1=NULL;buffer*Calbuf2=NULL;intnCal;while(m_end){Sleep(10);//因为计算线程的速度远远快于输入与输出线程,所以它的休眠时间应很小////同步与互斥的控制WaitForSingleObject(hsemINQ,INFINITE);WaitForSingleObject(hmutexINQ,INFINITE);Calbuf1=getBuf(INQ);//从输入队列中提取一个收容输入缓冲区nCal=Calbuf1-buf;//提取数据cout计算线程从缓冲单元Calbuf1-BufNo---提取输入---data=Calbuf1-bufendl;//Calbuf-buf=-1;//系统将收回此缓冲区,表示该缓冲区已空ReleaseMutex(hmutexINQ);WaitForSingleObject(hmutexEMQ,INFINITE);putBuf(EMQ,Calbuf1);ReleaseMutex(hmutexEMQ);ReleaseSemaphore(hsemEMQ,1,NULL);nCal=nCal+10000;//模拟输入数据的处理WaitForSingleObject(hsemEMQ,INFINITE);WaitForSingleObject(hmutexEMQ,INFINITE);Calbuf2=getBuf(EMQ);//得到一个空的缓冲区作为收容输出Calbuf2-buf=nCal;//存入运算结果cout计算线程从缓冲单元Calbuf2-BufNo---收容输出---data=Calbuf2-bufendl;ReleaseMutex(hmutexEMQ);WaitForSingleObject(hmutexOUTQ,INFINITE);//把收容输出缓冲区挂载到输出队列的队尾putBuf(OUTQ,Calbuf2);ReleaseMutex(hmutexOUTQ);ReleaseSemaphore(hsemOUTQ,1,NULL);}return0;}//从队列中得到队头结点函数(实际相当于删除一个结点操作)buffer*getBuf(inttype){buffer*Returnbuf=NULL;switch(type){case0:{//判断该队列的缓冲个数是否还只有一个if(hemq!=lemq&&hemq-next-next!=NULL){Returnbuf=hemq-next;//取得队列头hemq-next=Returnbuf-next;//修正队列链表头指针的指向Returnbuf-next=NULL;returnReturnbuf;}else{//假如该缓冲队列的个数只有一个的话,则使得队头指针与队尾指针相等级//这样的话就可以防止队尾指针的丢失Returnbuf=hemq-next;hemq-next=Returnbuf-next;Returnbuf-next=NULL;lemq=hemq;returnReturnbuf;}}break;case1:{if(hinq!=linq&&hinq-next-next!=NULL){Returnbuf=hinq-next;hinq-next=Returnbuf-next;Returnbuf-next=NULL;returnReturnbuf;}else{Returnbuf=hinq-next;hinq-next=Returnbuf-next;Re
本文标题:缓冲池的模拟使用
链接地址:https://www.777doc.com/doc-3878965 .html