操作系統實驗報告-進程間通信_第1頁
操作系統實驗報告-進程間通信_第2頁
操作系統實驗報告-進程間通信_第3頁
操作系統實驗報告-進程間通信_第4頁
操作系統實驗報告-進程間通信_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

實驗題目實驗目的掌握用郵箱方式進行進程通信的方法,并通過設計實現簡單郵箱理解進程通信中的同步問題以及解決該問題的方法。實驗環(huán)境WindowsXPSP3實驗原理郵箱機制類似于日常使用的信箱。對于用戶而言使用起來比較方便,用戶只需使用send()向對方郵箱發(fā)郵件receive()從自己郵箱取郵件,send()和receive()的內部操作用戶無需關心。因為郵箱在內存中實現,其空間有大小限制。其實send()和receive()的內部實現主要還是要解決生產者與消費者問題。實驗內容進程通信的郵箱方式由操作系統提供形如send()和receive()的系統調用來支持,本實驗要求學生首先查找資料了解所選用操作系統平臺上用于進程通信的系統調用具體形式,然后使用該系統調用編寫程序進行進程間的通信,要求程序運行結果可以直觀地體現在界面上。在此基礎上查找所選用操作系統平臺上支持信號量機制的系統調用具體形式,運用生產者與消費者模型設計實現一個簡單的信箱,該信箱需要有創(chuàng)建、發(fā)信、收信、撤銷等函數,至少能夠支持兩個進程互相交換信息,比較自己實現的信箱與操作系統本身提供的信箱,分析兩者之間存在的異同。Mutex和Semaphore區(qū)別在windows環(huán)境下兩者有著類似之處但不完全相同。Semaphore可以比喻成是一個銀行(臨界區(qū))有N人的服務窗口(最大允許同步進程數量),如果申請的客戶(進程)少于N就可以辦理業(yè)務,如果客戶滿了,就要等待某一個客戶服務的結束。Mutex可以比喻成是一個銀行只有1各服務窗口,如果客戶A正在辦理,那么后續(xù)客戶申請時只能等待,只有當客戶A辦理結束離開服務窗口時,后續(xù)客戶依據申請順序逐一獲得被服務的資格。Mutex在沒有被任何線程所擁有時是有信號的,這時任何線程可以使用Waitfunctions去獲取該對象的所有權。當Mutex被某個線程擁有后就處于沒信號狀態(tài),并且只有當該線程使用ReleaseMutex釋放該互斥對象時,它才能被其它線程獲得。在windows環(huán)境下一個線程中試圖釋放另個線程所擁有的Mutex是不會成功的,Mutex只能被所有者線程所釋放。在前面的例子中就是不允許插隊。Semaphore可以被其他進程釋放在前面的例子中就是允許插隊,這樣會導致超過允許服務的進程上限共享內存實現郵箱的數據結構由于共享內存的方法不直接提供隊列功能故采用循環(huán)隊列思想模擬緩沖區(qū),下面是共享內存的頭部,用來存儲索引信息struct{DWORDMsgSize;//單個消息大?。鹤止?jié)數intMsgMaxCount;//消息的總數intMsgNum;//消息的個數intReadIndex;//可讀消息索引intWriteIndex;//可寫消息索引};“實時”顯示內容的處理與內存泄漏這個顯示消息的函數每隔50ms執(zhí)行一次,所以實際上是是查詢方式來實現實時顯示在此模式下可以發(fā)現一些被人遺忘的內存釋放,我在實現這個函數時候發(fā)現進程占用內存和執(zhí)行時間成正比,最后才發(fā)現內存泄漏的地方,尤其是讀取共享內存的指針特別占內存相關代碼聲明類enumoperation{SpaceEnum,SendEnum,ReceiveEnum,MutexEnum};typedefstruct_MSGQ_HEADER{DWORDMsgSize; //單個消息大?。鹤止?jié)數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; //發(fā)送信號量HANDLEm_SemaphoreReceive; //接收信號量HANDLEm_hFileMap; //文件映像句柄LPVOIDm_hViewBuf; //文件映像映射到地址空間的首地址LPCTSTR**strName;intnowProcess;DWORD*msgSize;int*msgCnt;};創(chuàng)建函數實現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];//先創(chuàng)建文件映像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("創(chuàng)建共享內存失敗"));returnFALSE;}//映射文件映像m_hViewBuf=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);//映射全部Bufferif(m_hViewBuf==NULL){QMessageBox::information(NULL,tr("提示"),tr("讀取共享內存失敗"));returnFALSE;}//信號量創(chuàng)建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;}//打開目的地郵箱的發(fā)送信號量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)//環(huán)形QueuepotherMsgInfo->WriteIndex=0;ReleaseMutex(openmutex);bRet=TRUE;}//V操作ReleaseSemaphore(other_SemaphoreReceive,1,NULL);}elseif(dRet==WAIT_TIMEOUT){QMessageBox::information(NULL,tr("提示"),tr("對方郵箱已滿,發(fā)送失敗"));}//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;//打開本地郵箱的發(fā)送信號量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)//環(huán)形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. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論