操作系统实验报告 进程间通信.docx
- 文档编号:23717274
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:14
- 大小:56.46KB
操作系统实验报告 进程间通信.docx
《操作系统实验报告 进程间通信.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告 进程间通信.docx(14页珍藏版)》请在冰豆网上搜索。
操作系统实验报告进程间通信
《计算机操作系统》
实验报告
(二)
学号:
030702412姓名:
陈楠
学院:
数计学院专业:
计算机类
年级:
2007级班级:
4班
实验时间:
2009-2010学年第一学期
指导教师:
丁善镜、黄志华
1、实验题目
2、实验目的
掌握用邮箱方式进行进程通信的方法,并通过设计实现简单邮箱理解进程通信中的同步问题以及解决该问题的方法。
3、实验环境
WindowsXPSP3
4、实验原理
邮箱机制类似于日常使用的信箱。
对于用户而言使用起来比较方便,用户只需使用send()向对方邮箱发邮件receive()从自己邮箱取邮件,send()和receive()的内部操作用户无需关心。
因为邮箱在内存中实现,其空间有大小限制。
其实send()和receive()的内部实现主要还是要解决生产者与消费者问题。
5、实验内容
进程通信的邮箱方式由操作系统提供形如send()和receive()的系统调用来支持,本实验要求学生首先查找资料了解所选用操作系统平台上用于进程通信的系统调用具体形式,然后使用该系统调用编写程序进行进程间的通信,要求程序运行结果可以直观地体现在界面上。
在此基础上查找所选用操作系统平台上支持信号量机制的系统调用具体形式,运用生产者与消费者模型设计实现一个简单的信箱,该信箱需要有创建、发信、收信、撤销等函数,至少能够支持两个进程互相交换信息,比较自己实现的信箱与操作系统本身提供的信箱,分析两者之间存在的异同。
5.1、Mutex和Semaphore区别
¢在windows环境下两者有着类似之处但不完全相同。
¢Semaphore可以比喻成是一个银行(临界区)有N人的服务窗口(最大允许同步进程数量),如果申请的客户(进程)少于N就可以办理业务,如果客户满了,就要等待某一个客户服务的结束。
¢Mutex可以比喻成是一个银行只有1各服务窗口,如果客户A正在办理,那么后续客户申请时只能等待,只有当客户A办理结束离开服务窗口时,后续客户依据申请顺序逐一获得被服务的资格。
¢Mutex在没有被任何线程所拥有时是有信号的,这时任何线程可以使用Waitfunctions去获取该对象的所有权。
当Mutex被某个线程拥有后就处于没信号状态,并且只有当该线程使用ReleaseMutex释放该互斥对象时,它才能被其它线程获得。
¢在windows环境下一个线程中试图释放另个线程所拥有的Mutex是不会成功的,Mutex只能被所有者线程所释放。
¢在前面的例子中就是不允许插队。
¢Semaphore可以被其他进程释放
¢在前面的例子中就是允许插队,这样会导致超过允许服务的进程上限
5.2、共享内存实现邮箱的数据结构
¢由于共享内存的方法不直接提供队列功能故采用循环队列思想模拟缓冲区,下面是共享内存的头部,用来存储索引信息
¢struct
¢{
•DWORDMsgSize;//单个消息大小:
字节数
•intMsgMaxCount;//消息的总数
•intMsgNum;//消息的个数
•intReadIndex;//可读消息索引
•intWriteIndex;//可写消息索引
¢};
5.3、“实时”显示内容的处理与内存泄漏
¢这个显示消息的函数每隔50ms执行一次,所以实际上是是查询方式来实现实时显示
¢在此模式下可以发现一些被人遗忘的内存释放,我在实现这个函数时候发现进程占用内存和执行时间成正比,最后才发现内存泄漏的地方,尤其是读取共享内存的指针特别占内存
5.4、相关代码
5.4.1、声明类
1)enumoperation{SpaceEnum,SendEnum,ReceiveEnum,MutexEnum};
2)typedefstruct_MSGQ_HEADER
3){
4)DWORDMsgSize;//单个消息大小:
字节数
5)intMsgMaxCount;//消息的总数
6)intMsgNum;//消息的个数
7)intReadIndex;//可读消息索引
8)intWriteIndex;//可写消息索引
9)}MSGQ_HEADER,*PMSGQ_HEADER;
10)
11)classCMsgQ:
publicQDialog
12){
13)public:
14)CMsgQ(){}
15)
16)BOOLCreate(LPCTSTR**strname,intnowProcess,intmaxProcess,int*MsgMaxCount,DWORD*MsgSize);
17)
18)BOOLGetMsgQInfo(PDWORDmsgSize,PDWORDmsgCnt);
19)
20)BOOLSend(LPVOIDbuf,intwhichProcess,DWORDwaitTime=INFINITE);
21)BOOLReceive(LPVOIDbuf,DWORDwaitTime=INFINITE);
22)intRead(char**ReadMailBox);
23)
24)private:
25)PMSGQ_HEADERpMsgInfo;
26)HANDLEm_hMutex;
27)HANDLEm_SemaphoreSend;//发送信号量
28)HANDLEm_SemaphoreReceive;//接收信号量
29)HANDLEm_hFileMap;//文件映像句柄
30)LPVOIDm_hViewBuf;//文件映像映射到地址空间的首地址
31)
32)LPCTSTR**strName;
33)intnowProcess;
34)DWORD*msgSize;
35)int*msgCnt;
36)};
5.4.2、创建函数实现
1)BOOLCMsgQ:
:
Create(LPCTSTR**strname,intnowprocess,intmaxprocess,int*msgmaxcount,DWORD*msgsize)
2){
3)inti,j;
4)strName=newLPCTSTR*[maxprocess];
5)for(i=0;i 6)strName[i]=newLPCTSTR[4]; 7)for(i=0;i 8)for(j=0;j<4;j++) 9)strName[i][j]=strname[i][j]; 10)nowProcess=nowprocess; 11)msgSize=newDWORD[maxprocess]; 12)for(i=0;i 13)msgSize[i]=msgsize[i]; 14)msgCnt=newint[maxprocess]; 15)for(i=0;i 16)msgCnt[i]=msgmaxcount[i]; 17)//先创建文件映像 18)m_hMutex=CreateMutex(NULL,false,strname[nowProcess][MutexEnum]); 19) 20)m_hFileMap=CreateFileMapping(INVALID_HANDLE_VALUE,NULL, 21)PAGE_READWRITE,0,sizeof(_MSGQ_HEADER)+ 22)sizeof(char)*msgCnt[nowProcess],strname[nowProcess][SpaceEnum]); 23)if(m_hFileMap==NULL) 24){ 25)QMessageBox: : information(NULL,tr("提示"), 26)tr("创建共享内存失败")); 27)returnFALSE; 28)} 29)//映射文件映像 30) 31)m_hViewBuf=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);//映射全部Buffer 32)if(m_hViewBuf==NULL) 33){ 34)QMessageBox: : information(NULL,tr("提示"), 35)tr("读取共享内存失败")); 36)returnFALSE; 37)} 38) 39)//信号量创建 40)m_SemaphoreSend=CreateSemaphore(NULL,msgCnt[nowProcess],msgCnt[nowProcess],strname[nowProcess][SendEnum]); 41)m_SemaphoreReceive=CreateSemaphore(NULL,0,msgCnt[nowProcess],strname[nowProcess][ReceiveEnum]); 42) 43)//设置MsgQ头信息 44){ 45)pMsgInfo=(_MSGQ_HEADER*)m_hViewBuf; 46)pMsgInfo->MsgMaxCount=msgCnt[nowProcess]; 47)pMsgInfo->MsgSize=msgSize[nowProcess]; 48)pMsgInfo->ReadIndex=0; 49)pMsgInfo->WriteIndex=0;//从索引0开始写 50)pMsgInfo->MsgNum=0; 51) 52)//ReleaseMutex(m_Semaphore); 53)} 54)returnTRUE; 55)} 5.4.3、Send()函数实现 1)BOOLCMsgQ: : Send(LPVOIDbuf,intwhichProcess,DWORDwaitTime) 2){ 3)LPCVOIDori; 4)char*lpchar;//地址指针 5)BOOLbRet=FALSE;//返回值判断 6)_MSGQ_HEADER*potherMsgInfo;//目的地的队列索引 7) 8)//打开目的地的邮箱 9)HANDLEother_hFileMap=OpenFileMapping(FILE_MAP_WRITE,FALSE,strName[whichProcess][SpaceEnum]); 10)if(other_hFileMap==NULL) 11){ 12)QMessageBox: : information(NULL,tr("提示"), 13)tr("打开共享内存失败")); 14)returnFALSE; 15)} 16) 17)//打开目的地邮箱的发送信号量 18)HANDLEother_SemaphoreSend=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[whichProcess][SendEnum]); 19)//打开目的地邮箱的接受信号量 20)HANDLEother_SemaphoreReceive=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[whichProcess][ReceiveEnum]); 21) 22) 23)//ReleaseSemaphore(other_Semaphore,1,NULL); 24)//打开目的地邮箱的空间 25)QProcessgzip; 26)gzip.start("clock.exe",QStringList()<<"28"); 27)DWORDdRet=WaitForSingleObject(other_SemaphoreSend,waitTime); 28) 29)ori=MapViewOfFile(other_hFileMap,FILE_MAP_WRITE,0,0,0); 30)lpchar=(char*)ori; 31)potherMsgInfo=(_MSGQ_HEADER*)lpchar; 32) 33)HANDLEopenmutex=OpenMutex(MUTEX_ALL_ACCESS,false,strName[whichProcess][MutexEnum]); 34)//P操作 35) 36) 37)if(dRet==WAIT_OBJECT_0) 38){ 39)gzip.close(); 40)if(potherMsgInfo->MsgNum! =potherMsgInfo->MsgMaxCount)//再次判断是否可写 41){ 42)WaitForSingleObject(openmutex,waitTime); 43)potherMsgInfo->MsgNum++; 44)lpchar+=sizeof(_MSGQ_HEADER)+sizeof(char)*potherMsgInfo->MsgSize*potherMsgInfo->WriteIndex; 45)strcpy(lpchar,(char*)buf); 46) 47)if(++potherMsgInfo->WriteIndex==potherMsgInfo->MsgMaxCount)//环形Queue 48)potherMsgInfo->WriteIndex=0; 49)ReleaseMutex(openmutex); 50)bRet=TRUE; 51)} 52)//V操作 53)ReleaseSemaphore(other_SemaphoreReceive,1,NULL); 54)}elseif(dRet==WAIT_TIMEOUT) 55){ 56)QMessageBox: : information(NULL,tr("提示"), 57)tr("对方邮箱已满,发送失败")); 58)} 59)//CloseHandle(other_hViewBuf); 60)UnmapViewOfFile(ori); 61)CloseHandle(openmutex); 62)CloseHandle(other_hFileMap); 63)CloseHandle(other_SemaphoreSend); 64)CloseHandle(other_SemaphoreReceive); 65)CloseHandle(other_SemaphoreReceive); 66)returnbRet; 67)} 5.4.4、Receive()函数实现 1)BOOLCMsgQ: : Receive(LPVOIDbuf,DWORDwaitTime) 2){ 3)LPCVOIDori; 4)char*lpchar; 5)BOOLbRet=FALSE; 6)//打开本地邮箱的发送信号量 7)HANDLEmy_SemaphoreSend=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[nowProcess][SendEnum]); 8)//打开本地地邮箱的接受信号量 9)HANDLEmy_SemaphoreReceive=OpenSemaphore(SEMAPHORE_ALL_ACCESS,FALSE,strName[nowProcess][ReceiveEnum]); 10) 11)DWORDdRet=WaitForSingleObject(my_SemaphoreReceive,waitTime); 12) 13)if(dRet==WAIT_OBJECT_0) 14){ 15)if(pMsgInfo->MsgNum! =0)//再次判断是否可读 16){ 17)ori=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0); 18)lpchar=(char*)ori; 19)lpchar+=sizeof(_MSGQ_HEADER)+sizeof(char)*msgSize[nowProcess]*pMsgInfo->ReadIndex; 20)strcpy((char*)buf,lpchar); 21)lpchar[0]='\0'; 22)pMsgInfo->MsgNum--; 23)if(++pMsgInfo->ReadIndex==pMsgInfo->MsgMaxCount)//环形Queue 24)pMsgInfo->ReadIndex=0; 25) 26)bRet=TRUE; 27)} 28)ReleaseSemaphore(my_SemaphoreSend,1,NULL); 29)}elseif(dRet==WAIT_TIMEOUT) 30){ 31)QMessageBox: : information(NULL,tr("提示"), 32)tr("本进程邮箱已空,不可接收信息")); 33)} 34)UnmapViewOfFile(ori); 35)CloseHandle(my_SemaphoreSend); 36)CloseHandle(my_SemaphoreReceive); 37)returnbRet; 38)} 5.4.5、实时显示函数 1)intCMsgQ: : Read(char**ReadMailBox) 2){ 3)LPCVOIDori; 4)char*lpchar; 5)inti; 6)for(i=0;i 7)ReadMailBox[i][0]='\0'; 8)i=0; 9)while(i! =pMsgInfo->MsgMaxCount) 10){ 11)//ori=MapViewOfFile(m_hFileMap,FILE_MAP_READ,0,0,0); 12)ori=m_hViewBuf; 13)lpchar=(char*)ori; 14)lpchar+=sizeof(_MSGQ_HEADER)+sizeof(char)*msgSize[nowProcess] 15)*((pMsgInfo->ReadIndex+i)%pMsgInfo->MsgMaxCount); 16)strcpy(ReadMailBox[i++],lpchar); 17)if((pMsgInfo->ReadIndex+i)%pMsgInfo->MsgMaxCount==pMsgInfo->WriteIndex)//环形Queue 18)break; 19)//UnmapViewOfFile(ori); 20)} 21)returni; 22)} 6、演示效果图
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统实验报告 进程间通信 操作系统 实验 报告 进程 通信
![提示](https://static.bdocx.com/images/bang_tan.gif)