版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
《计算机操作系统》实验报告〔二〕
目录TOC\o"1-4"\h\z\u1、 实验题目 32、 实验目的 33、 实验环境 34、 实验原理 35、 实验内容 35.1、 fork()函数机理探索 35.1.1、 原始代码段 35.1.2、 代码段修改一 35.1.3、 结论(1) 45.1.4、 fock()函数原理 45.1.5、 代码段修改二 45.2、 并发执行测猜想 55.2.1、 并发执行改良 55.2.2、 代码段修改〔3〕 55.3、 小结 6实验题目实验目的掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。实验环境WindowsXPSP3实验原理邮箱机制类似于日常使用的信箱。对于用户而言使用起来比拟方便,用户只需使用send〔〕向对方邮箱发邮件receive〔〕从自己邮箱取邮件,send〔〕和receive〔〕的内部操作用户无需关心。因为邮箱在内存中实现,其空间有大小限制。其实send〔〕和receive〔〕的内部实现主要还是要解决生产者与消费者问题。实验内容进程通信的邮箱方式由操作系统提供形如send〔〕和receive〔〕的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地表达在界面上。在此根底上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创立、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比拟自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。Mutex和Semaphore区别在windows环境下两者有着类似之处但不完全相同。Semaphore可以比喻成是一个银行〔临界区〕有N人的效劳窗口〔最大允许同步进程数量〕,如果申请的客户〔进程〕少于N就可以办理业务,如果客户满了,就要等待某一个客户效劳的结束。Mutex可以比喻成是一个银行只有1各效劳窗口,如果客户A正在办理,那么后续客户申请时只能等待,只有当客户A办理结束离开效劳窗口时,后续客户依据申请顺序逐一获得被效劳的资格。Mutex在没有被任何线程所拥有时是有信号的,这时任何线程可以使用Waitfunctions去获取该对象的所有权。当Mutex被某个线程拥有后就处于没信号状态,并且只有当该线程使用ReleaseMutex释放该互斥对象时,它才能被其它线程获得。在windows环境下一个线程中试图释放另个线程所拥有的Mutex是不会成功的,Mutex只能被所有者线程所释放。在前面的例子中就是不允许插队。Semaphore可以被其他进程释放在前面的例子中就是允许插队,这样会导致超过允许效劳的进程上限共享内存实现邮箱的数据结构由于共享内存的方法不直接提供队列功能故采用循环队列思想模拟缓冲区,下面是共享内存的头部,用来存储索引信息struct{DWORDMsgSize;//单个消息大小:字节数intMsgMaxCount;//消息的总数intMsgNum;//消息的个数intReadIndex;//可读消息索引intWriteIndex;//可写消息索引};“实时”显示内容的处理与内存泄漏这个显示消息的函数每隔50ms执行一次,所以实际上是是查询方式来实现实时显示在此模式下可以发现一些被人遗忘的内存释放,我在实现这个函数时候发现进程占用内存和执行时间成正比,最后才发现内存泄漏的地方,尤其是读取共享内存的指针特别占内存相关代码声明类enumoperation{SpaceEnum,SendEnum,ReceiveEnum,MutexEnum};typedefstruct_MSGQ_HEADER{DWORDMsgSize; //单个消息大小:字节数intMsgMaxCount; //消息的总数intMsgNum; //消息的个数intReadIndex; //可读消息索引intWriteIndex; //可写消息索引}MSGQ_HEADER,*PMSGQ_HEADER;classCMsgQ:publicQDialog{public:CMsgQ(){}BOOLCreate(LPCTSTR**strname,intnowProcess,intmaxProcess,int*MsgMaxCount,DWORD*MsgSize);BOOLGetMsgQInfo(PDWORDmsgSize,PDWORDmsgCnt);BOOLSend(LPVOIDbuf,intwhichProcess,DWORDwaitTime=INFINITE);BOOLReceive(LPVOIDbuf,DWORDwaitTime=INFINITE);intRead(char**ReadMailBox);private:PMSGQ_HEADERpMsgInfo;HANDLEm_hMutex;HANDLEm_SemaphoreSend; //发送信号量HANDLEm_SemaphoreReceive; //接收信号量HANDLEm_hFileMap; //文件映像句柄LPVOIDm_hViewBuf; //文件映像映射到地址空间的首地址LPCTSTR**strName;intnowProcess;DWORD*msgSize;int*msgCnt;};创立函数实现BOOLCMsgQ::Create(LPCTSTR**strname,intnowprocess,intmaxprocess,int*msgmaxcount,DWORD*msgsize){inti,j;strName=newLPCTSTR*[maxprocess];for(i=0;i<maxprocess;i++)strName[i]=newLPCTSTR[4];for(i=0;i<maxprocess;i++)for(j=0;j<4;j++)strName[i][j]=strname[i][j];nowProcess=nowprocess;msgSize=newDWORD[maxprocess];for(i=0;i<maxprocess;i++)msgSize[i]=msgsize[i];msgCnt=newint[maxprocess];for(i=0;i<maxprocess;i++)msgCnt[i]=msgmaxcount[i];//先创立文件映像m_hMutex=CreateMutex(NULL,false,strname[nowProcess][MutexEnum]);m_hFileMap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE,0,sizeof(_MSGQ_HEADER)+sizeof(char)*msgCnt[nowProcess],strname[nowProcess][SpaceEnum]);if(m_hFileMap==NULL){QMessageBox::information(NULL,tr("提示"),tr("创立共享内存失败"));returnFALSE;}//映射文件映像m_hViewBuf=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);//映射全部Bufferif(m_hViewBuf==NULL){QMessageBox::information(NULL,tr("提示"),tr("读取共享内存失败"));returnFALSE;}//信号量创立m_SemaphoreSend=CreateSemaphore(NULL,msgCnt[nowProcess],msgCnt[nowProcess],strname[nowProcess][SendEnum]);m_SemaphoreReceive=CreateSemaphore(NULL,0,msgCnt[nowProcess],strname[nowProcess][ReceiveEnum]);//设置MsgQ头信息{pMsgInfo=(_MSGQ_HEADER*)m_hViewBuf;pMsgInfo->MsgMaxCount=msgCnt[nowProcess];pMsgInfo->MsgSize=msgSize[nowProcess];pMsgInfo->ReadIndex=0;pMsgInfo->WriteIndex=0;//从索引0开始写pMsgInfo->MsgNum=0;//ReleaseMutex(m_Semaphore);}returnTRUE;}Send()函数实现BOOLCMsgQ::Send(LPVOIDbuf,intwhichProcess,DWORDwaitTime){LPCVOIDori;char*lpchar; //地址指针BOOLbRet=FALSE; //返回值判断_MSGQ_HEADER*potherMsgInfo; //目的地的队列索引//翻开目的地的邮箱HANDLEother_hFileMap=OpenFileMapping(FILE_MAP_WRITE,FALSE,strName[whichProcess][SpaceEnum]);if(other_hFileMap==NULL){QMessageBox::information(NULL,tr("提示"),tr("翻开共享内存失败"));returnFALSE;}//翻开目的地邮箱的发送信号量HANDLEother_SemaphoreSend=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[whichProcess][SendEnum]);//翻开目的地邮箱的接受信号量HANDLEother_SemaphoreReceive=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[whichProcess][ReceiveEnum]);//ReleaseSemaphore(other_Semaphore,1,NULL);//翻开目的地邮箱的空间QProcessgzip;gzip.start("clock.exe",QStringList()<<"28");DWORDdRet=WaitForSingleObject(other_SemaphoreSend,waitTime);ori=MapViewOfFile(other_hFileMap,FILE_MAP_WRITE,0,0,0);lpchar=(char*)ori;potherMsgInfo=(_MSGQ_HEADER*)lpchar;HANDLEopenmutex=OpenMutex(MUTEX_ALL_ACCESS,false,strName[whichProcess][MutexEnum]);//P操作if(dRet==WAIT_OBJECT_0){gzip.close();if(potherMsgInfo->MsgNum!=potherMsgInfo->MsgMaxCount)//再次判断是否可写{WaitForSingleObject(openmutex,waitTime);potherMsgInfo->MsgNum++;lpchar+=sizeof(_MSGQ_HEADER)+sizeof(char)*potherMsgInfo->MsgSize*potherMsgInfo->WriteIndex;strcpy(lpchar,(char*)buf);if(++potherMsgInfo->WriteIndex==potherMsgInfo->MsgMaxCount)//环形QueuepotherMsgInfo->WriteIndex=0;ReleaseMutex(openmutex);bRet=TRUE;}//V操作ReleaseSemaphore(other_SemaphoreReceive,1,NULL);}elseif(dRet==WAIT_TIMEOUT){QMessageBox::information(NULL,tr("提示"),tr("对方邮箱已满,发送失败"));}//CloseHandle(other_hViewBuf);UnmapViewOfFile(ori);CloseHandle(openmutex);CloseHandle(other_hFileMap);CloseHandle(other_SemaphoreSend);CloseHandle(other_SemaphoreReceive);CloseHandle(other_SemaphoreReceive);returnbRet;}Receive()函数实现BOOLCMsgQ::Receive(LPVOIDbuf,DWORDwaitTime){LPCVOIDori;char*lpchar;BOOLbRet=FALSE;//翻开本地邮箱的发送信号量HANDLEmy_SemaphoreSend=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[nowProcess][SendEnum]);//翻开本地地邮箱的接受信号量HANDLEmy_SemaphoreReceive=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[nowProcess][ReceiveEnum]);DWORDdRet=WaitForSingleObject(my_SemaphoreReceive,waitTime);if(dRet==WAIT_OBJECT_0){if(pMsgInfo->MsgNum!=0)//再次判断是否可读{ori=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);lpchar=(char*)ori;lpchar+=sizeof(_MSGQ_HEADER)+sizeof(char)*msgSize[nowProcess]*pMsgInfo->ReadIndex;strcpy((char*)buf,lpchar);lpchar[0]='\0';pMsgInfo->MsgNum--;if(++pMsgInfo->ReadIndex==pMsgInfo->MsgMaxCount)//环形QueuepMsgInfo->ReadIndex=0;bRet=TRUE;}ReleaseSemaphore(my_SemaphoreSend,1,NULL);}elseif(dRet==WAIT_TIMEOUT){QMessageBox::information(NULL,t
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年巴中市中心医院关于招聘74名员额管理专业技术人员的备考题库及一套完整答案详解
- 2026年厦门市集美区三社小学产假顶岗教师招聘备考题库及参考答案详解
- 2026年中山大学孙逸仙纪念医院深汕中心医医务科病案室合同医技岗位招聘备考题库及一套完整答案详解
- 2026年广东省韶铸集团有限公司(韶关铸锻总厂)招聘备考题库及答案详解一套
- 2026年安徽皖信人力资源管理有限公司红河分公司招聘政企客户经理备考题库及答案详解参考
- 2026年北京日报社公开招聘备考题库有答案详解
- 2026年乐平市公开招聘城市社区工作者(专职网格员)30人备考题库及参考答案详解一套
- 2026年北京市海淀区中关村第三小学教育集团幼儿园备考题库及1套完整答案详解
- 2026年关于广东龙门产业投资集团有限公司公开招聘三名职工的备考题库及参考答案详解一套
- 2026年广州花都基金管理有限公司招聘备考题库及答案详解参考
- 2025年中职食品雕刻(食品雕刻技术)试题及答案
- 2026青海西宁市湟源县水务发展(集团)有限责任公司招聘8人考试参考试题及答案解析
- 2025年大学(运动康复)运动康复治疗技术测试试题及答案
- 1256《数据库应用技术》国家开放大学期末考试题库
- 配电红外测温课件
- 美容院店长年度总结课件
- 江苏省2025年普通高中学业水平合格性考试历史试卷(含答案详解)
- 小学阶段人工智能在激发学生学习动机中的应用研究教学研究课题报告
- 2025年山西大地环境投资控股有限公司社会招聘116人备考题库及完整答案详解一套
- 民爆三大员培训题库及答案
- (2025年)昆山杜克大学ai面试真题附答案
评论
0/150
提交评论