完整word版操作系统 缓冲池的模拟使用word文档良心出品.docx
- 文档编号:30302836
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:15
- 大小:167.32KB
完整word版操作系统 缓冲池的模拟使用word文档良心出品.docx
《完整word版操作系统 缓冲池的模拟使用word文档良心出品.docx》由会员分享,可在线阅读,更多相关《完整word版操作系统 缓冲池的模拟使用word文档良心出品.docx(15页珍藏版)》请在冰豆网上搜索。
完整word版操作系统缓冲池的模拟使用word文档良心出品
GDOU-B-11-112
广东海洋大学学生实验报告书(学生用表)
、实验目的
(1)掌握缓冲池的结构
(2)掌握缓冲池的使用方法
二、实验内容
1、实现输入、计算、输出进程并发执行;
2、实现getBuf和putBuf函数。
三、实验步骤
还有三个
1、整体设计,包括三个线程的模拟设计,三个队列的链表设计,队列的同步与互斥的设计等;
2、由于本次实验没有需要太多的数据结构,因此,数据结构的设计就只有三个缓冲队列的设计:
先构造一个空的缓冲队列,该队列是一个实体,即旦确定的有结点的链表,它是模拟缓冲池的载体,输入与输出队列在构造时只有它的头尾指针,而没有它的实体,这是因为它可以从空缓冲区里获得,例如,当计
算线程要数据计算时,便可从空队列里获取一个缓冲区,作为输入缓冲使用再把它挂载到输入队列的队尾中去
由于要写的内容比较多,这里就不再废话连篇了,先把代码贴出来,里面有着注释呢,大家都懂的:
头文件如下:
0〃空缓冲队列
1〃输入缓冲队列
//缓冲队列类型的定义
#defineEMQ
#defineINQ
#defineOUTQ2〃输出缓冲队列
〃显示的宏定义
#defineshow1
III
byCLC
软件1103
#defineshow2
III
#defineshow3
III
constintbufferpoolsize=50;////缓冲池大小,默认设置为50个
〃结束运行标志
shortintm_end;
〃缓冲结构体的定义
typedefstructBuffer
{
intBufNo;〃缓冲区号
intbuf;〃缓冲内容
Buffer*next;//缓冲指向下一个指针
}buffer;
//线程函数声明
DWORDWINAPIInputThreadFunc(LPVOIDIpPara);//输入线程函数DWORDWINAPIOutputThreadFunc(LPVOIDIpPara);//输出线程函数DWORDWINAPICalThreadFunc(LPVOIDIpPara);//计算线程函数
〃构造缓冲池函数的声明
voidConstructBuffer();
〃三个互斥量信号句柄
HANDLEhmutexEMQ;
HANDLEhmutexOUTQ;
HANDLEhmutexINQ;
〃三个同步信号量
HANDLEhsemINQ;
HANDLEhsemOUTQ;
HANDLEhsemEMQ;
Cpp的内容如下:
#include"windows.h"#include"iostream"#include"stdlib.h"
#include"time.h"#include"Main1.h"usingnamespacestd;
//三个缓冲队列头与尾指针buffer*hemq,*hinq,*houtq;
buffer*lemq,*linq,*loutq;
〃空队列的互斥信号量
〃装满输出队列的互斥信号量
〃装满输入队列的互斥信号量
〃队头指针
〃队尾指针
//主函数
intmain()
{
cout< m_end=1;//运行结束标志 ConstructBufferO;//构造缓冲池 //创建互斥对象 hmutexEMQ=CreateMutex(NULL,FALSE,NULL);hmutexOUTQ=CreateMutex(NULL,FALSE,NULL);hmutexINQ=CreateMutex(NULL,FALSE,NULL); 〃创建信号量对象 hsemINQ=CreateSemaphore(NULL,O,bufferpoolsize,NULL);hsemOUTQ=CreateSemaphore(NULL,0,bufferpoolsize,NULL); hsemEMQ=CreateSemaphore(NULL,bufferpoolsize,bufferpoolsize,NULL); 〃创建线程 hInputT=CreateThread(NULL,O,lnputThreadFunc,NULL,0,&lnputTid); 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; coutvv"程序已经终止! "< } 〃等待三个线程的结束返回 WaitForSingleObject(hlnputT,INFINITE); WaitForSingleObject(hCalculateT,INFINITE); WaitForSingleObject(hOutputT,INFINITE); 〃释放线程的资源 CloseHandle(hlnputT); CloseHandle(hCalculateT); CloseHandle(hOutputT); return0; } 〃输入线程函数的实现 DWORDWINAPIInputThreadFunc(LPVOIDIpPara)//输入线程函数{ intnRandom; 〃保证每次运行时产生的随机数独立 buffer*getbuf; srand(time(0)); while(m_end) {" Sleep(100); nRandom=rand()%100+1;//产生1至U100的随机数 //同步与互斥的控制 WaitForSingleObject(hsemEMQ,INFINITE); WaitForSingleObject(hmutexEMQ,INFINITE); getbuf=getBuf(EMQ);〃访问空队列getbuf->buf=nRandom; coutvv"输入线程从"<<"缓冲单元"< --->"vv"data="vvgetbuf->bufvvendl; ReleaseMutex(hmutexEMQ);〃释放互斥对象信号 //控制访问输入队列的互斥量 WaitForSingleObject(hmutexlNQ,INFINITE); putBuf(INQ,getbuf);〃将输入的缓冲区挂载到输入队列的队尾 ReleaseMutex(hmutexINQ); ReleaseSemaphore(hsemlNQ,1,NULL); } return0; } 〃输出线程函数的实现 DWORDWINAPIOutputThreadFunc(LPVOIDIpPara)〃输出线程函数 //一个临时交换区 { buffer*Outputbuf; while(m_end) {" Sleep(100); ////同步与互斥的控制 WaitForSingleObject(hsemOUTQ,INFINITE); WaitForSingleObject(hmutexOUTQ,INFINITE); Outputbuf=getBuf(OUTQ);//从输出队列中提取一个提取输出缓冲 coutvv"输出线程从"<<"缓冲单元"< //Outputbuf->buf=-1;〃提取完成后将该缓冲区回收 ReleaseMutex(hmutexOUTQ); WaitForSingleObject(hmutexEMQ,INFINITE); putBuf(EMQ,Outputbuf);〃回收的把它挂载到空队列的队尾 ReleaseMutex(hmutexEMQ); ReleaseSemaphore(hsemEMQ,1,NULL); } return0; } //计算线程函数 //计算线程函数的实现 DWORDWINAPICalThreadFunc(LPVOIDIpPara) { buffer*Calbuf1=NULL; buffer*Calbuf2=NULL; intnCal; while(m_end) {" Sleep(10);〃因为计算线程的速度远远快于输入与输出线程,所以它的休眠时间应很小 ////同步与互斥的控制 WaitForSingleObject(hsemlNQ,INFINITE); WaitForSingleObject(hmutexlNQ,INFINITE); Calbuf1=getBuf(INQ);//从输入队列中提取一个收容输入缓冲区 nCal=Calbuf1->buf;〃提取数据 coutvv"计算线程从"<<"缓冲单元"< //Calbuf->buf=-1;〃系统将收回此缓冲区,表示该缓冲区已空 ReleaseMutex(hmutexINQ); WaitForSingleObject(hmutexEMQ,INFINITE);putBuf(EMQ,Calbuf1); ReleaseMutex(hmutexEMQ); ReleaseSemaphore(hsemEMQ,1,NULL); WaitForSingleObject(hsemEMQ,INFINITE); WaitForSingleObject(hmutexEMQ,INFINITE); Calbuf2=getBuf(EMQ);〃得到一个空的缓冲区作为收容输出 Calbuf2->buf=nCal;//存入运算结果 coutvv"计算线程从"<<"缓冲单元"< --->"vv"data="< 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){ II取得队列头 //修正队列链表头指针的指 Returnbuf=hemq->next;hemq->next=Returnbuf->next; Returnbuf->next=NULL;returnReturnbuf; } else { 〃假如该缓冲队列的个数只有一个的话,贝u使得队头指针与队尾 指针相等级 〃这样的话就可以防止队尾指针的丢失 Returnbuf=hemq->next;hemq->next=Retumbuf->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=Retumbuf->next;Returnbuf->next=NULL; linq=hinq; returnReturnbuf; }break;case2: { if(houtq! =loutq&&houtq->next->next! =NULL){ Returnbuf=houtq->next;houtq->next=Returnbuf->next;Returnbuf->next=NULL;returnReturnbuf; } else { Returnbuf=houtq->next;houtq->next=Returnbuf->next;Returnbuf->next=NULL; loutq=houtq;returnReturnbuf; } }break; } }//把某一类型的缓冲区挂载到队尾函数〃(实际相当于插入一个结点操作)voidputBuf(inttype,buffer*buf) { switch(type) { case0: 〃该参数(buf)不为空的时候,才执行,因 〃修正队列尾指针 //队尾指针的跟踪 //队列尾指针赋空 { if(buf! =NULL) 为插入一个空的缓冲区是没有意义的 { lemq->next=buf;lemq=buf; lemq->next=NULL; } }break; case1: { if(buf! =NULL) { //同上 linq->next=buf; linq=buf; linq->next=NULL; } }break; case2: { if(buf! =NULL) { loutq->next=buf;loutq=buf; loutq->next=NULL;} }break; //构造缓冲池函数的声明voidConstructBuffer() { buffer*p,*q;hemq=newbuffer;hinq=newbuffer;houtq=newbuffer;q=hemq; for(inti=0;i //为开辟动态缓冲区而设的两个变量 //创建空队列的头指针 //创建输入队列的头指针 //创建输出队列的头指针 P=newbuffer;p->BufNo=i; p->buf=-1;q->next=p; q=P; //开辟新的缓冲区 //给开辟的缓冲区编号 //前一缓冲区指向新的缓冲区 //q总是记住队尾的缓冲区 } lemq=q;〃空缓冲区队尾指针的确定 linq=hinq;//此时输入与输出队列的头指针与尾指针是一致的 loutq=houtq; lemq->next=NULL; linq->next=NULL;loutq->next=NULL; 部分运行效果截图: 'D: \MVDOCUMENT名;砂-与作並\£二雷二学靜提炸乘統谣码区\山ngBLifferPooE\Oebijg\U...I■=■I同魂I 缓冲池的模拟 byCLC 软#1103 四、实验总结 1本次实验中,线程的同步与互斥和三个缓冲队列的维护是重点,在实际编程中,刚开始的时候没有太注重三个队列的维护,使得每次运行时都出现只有前面几个结果,后来认真的想想,原因在于是没有对这三个缓冲队列的维护,因 为三个队列都是以链表的形式来实现的,因此,出现了指针指向了系统非法的内 存地址,使得运行异常中止; 2、在PutBuf()与getBufO函数中并没有把线程访问的同步与互斥操作放 在里面,是因为是线程调用它时,返回后需要向屏幕打印消息,这样的话,多个线程便会抢占性的在屏幕上打印消息,会造成乱码的现象;假如要在putBufO与getBufO函数中包含互斥与同步的操作,那么势必要在这两个函数里面实现打印消息的; 3、体会了多线程编程的优越性,但,如果对各线程的同步与控制不恰当时,便会造成难以预料的结果,因此,用多线程编程时必须加以注意才行! 成绩 注: 请用A4纸书写,不够另附纸。 指导教师 日期
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整word版操作系统 缓冲池的模拟使用word文档良心出品 完整 word 操作系统 缓冲 模拟 使用 文档 良心 出品