操作系统实验报告-进程间通信_第1页
操作系统实验报告-进程间通信_第2页
操作系统实验报告-进程间通信_第3页
操作系统实验报告-进程间通信_第4页
操作系统实验报告-进程间通信_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验题目实验目的掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。实验环境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,tr("提示"),tr("本进程邮箱

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论