操作系統(tǒng)實(shí)驗報告-進(jìn)程間通信_第1頁
操作系統(tǒng)實(shí)驗報告-進(jìn)程間通信_第2頁
操作系統(tǒng)實(shí)驗報告-進(jìn)程間通信_第3頁
操作系統(tǒng)實(shí)驗報告-進(jìn)程間通信_第4頁
操作系統(tǒng)實(shí)驗報告-進(jìn)程間通信_第5頁
已閱讀5頁,還剩5頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

實(shí)驗題目實(shí)驗?zāi)康恼莆沼绵]箱方式進(jìn)行進(jìn)程通信的方法,并通過設(shè)計實(shí)現(xiàn)簡單郵箱理解進(jìn)程通信中的同步問題以及解決該問題的方法。實(shí)驗環(huán)境WindowsXPSP3實(shí)驗原理郵箱機(jī)制類似于日常使用的信箱。對于用戶而言使用起來比較方便,用戶只需使用send()向?qū)Ψ洁]箱發(fā)郵件receive()從自己郵箱取郵件,send()和receive()的內(nèi)部操作用戶無需關(guān)心。因為郵箱在內(nèi)存中實(shí)現(xiàn),其空間有大小限制。其實(shí)send()和receive()的內(nèi)部實(shí)現(xiàn)主要還是要解決生產(chǎn)者與消費(fèi)者問題。實(shí)驗內(nèi)容進(jìn)程通信的郵箱方式由操作系統(tǒng)提供形如send()和receive()的系統(tǒng)調(diào)用來支持,本實(shí)驗要求學(xué)生首先查找資料了解所選用操作系統(tǒng)平臺上用于進(jìn)程通信的系統(tǒng)調(diào)用具體形式,然后使用該系統(tǒng)調(diào)用編寫程序進(jìn)行進(jìn)程間的通信,要求程序運(yùn)行結(jié)果可以直觀地體現(xiàn)在界面上。在此基礎(chǔ)上查找所選用操作系統(tǒng)平臺上支持信號量機(jī)制的系統(tǒng)調(diào)用具體形式,運(yùn)用生產(chǎn)者與消費(fèi)者模型設(shè)計實(shí)現(xiàn)一個簡單的信箱,該信箱需要有創(chuàng)建、發(fā)信、收信、撤銷等函數(shù),至少能夠支持兩個進(jìn)程互相交換信息,比較自己實(shí)現(xiàn)的信箱與操作系統(tǒng)本身提供的信箱,分析兩者之間存在的異同。Mutex和Semaphore區(qū)別在windows環(huán)境下兩者有著類似之處但不完全相同。Semaphore可以比喻成是一個銀行(臨界區(qū))有N人的服務(wù)窗口(最大允許同步進(jìn)程數(shù)量),如果申請的客戶(進(jìn)程)少于N就可以辦理業(yè)務(wù),如果客戶滿了,就要等待某一個客戶服務(wù)的結(jié)束。Mutex可以比喻成是一個銀行只有1各服務(wù)窗口,如果客戶A正在辦理,那么后續(xù)客戶申請時只能等待,只有當(dāng)客戶A辦理結(jié)束離開服務(wù)窗口時,后續(xù)客戶依據(jù)申請順序逐一獲得被服務(wù)的資格。Mutex在沒有被任何線程所擁有時是有信號的,這時任何線程可以使用Waitfunctions去獲取該對象的所有權(quán)。當(dāng)Mutex被某個線程擁有后就處于沒信號狀態(tài),并且只有當(dāng)該線程使用ReleaseMutex釋放該互斥對象時,它才能被其它線程獲得。在windows環(huán)境下一個線程中試圖釋放另個線程所擁有的Mutex是不會成功的,Mutex只能被所有者線程所釋放。在前面的例子中就是不允許插隊。Semaphore可以被其他進(jìn)程釋放在前面的例子中就是允許插隊,這樣會導(dǎo)致超過允許服務(wù)的進(jìn)程上限共享內(nèi)存實(shí)現(xiàn)郵箱的數(shù)據(jù)結(jié)構(gòu)由于共享內(nèi)存的方法不直接提供隊列功能故采用循環(huán)隊列思想模擬緩沖區(qū),下面是共享內(nèi)存的頭部,用來存儲索引信息struct{DWORDMsgSize;//單個消息大小:字節(jié)數(shù)intMsgMaxCount;//消息的總數(shù)intMsgNum;//消息的個數(shù)intReadIndex;//可讀消息索引intWriteIndex;//可寫消息索引};“實(shí)時”顯示內(nèi)容的處理與內(nèi)存泄漏這個顯示消息的函數(shù)每隔50ms執(zhí)行一次,所以實(shí)際上是是查詢方式來實(shí)現(xiàn)實(shí)時顯示在此模式下可以發(fā)現(xiàn)一些被人遺忘的內(nèi)存釋放,我在實(shí)現(xiàn)這個函數(shù)時候發(fā)現(xiàn)進(jìn)程占用內(nèi)存和執(zhí)行時間成正比,最后才發(fā)現(xiàn)內(nèi)存泄漏的地方,尤其是讀取共享內(nèi)存的指針特別占內(nèi)存相關(guān)代碼聲明類enumoperation{SpaceEnum,SendEnum,ReceiveEnum,MutexEnum};typedefstruct_MSGQ_HEADER{DWORDMsgSize; //單個消息大?。鹤止?jié)數(shù)intMsgMaxCount; //消息的總數(shù)intMsgNum; //消息的個數(shù)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)建函數(shù)實(shí)現(xiàn)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)建共享內(nèi)存失敗"));returnFALSE;}//映射文件映像m_hViewBuf=MapViewOfFile(m_hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);//映射全部Bufferif(m_hViewBuf==NULL){QMessageBox::information(NULL,tr("提示"),tr("讀取共享內(nèi)存失敗"));returnFALSE;}//信號量創(chuàng)建m_SemaphoreSend=CreateSemaphore(NULL,msgCnt[nowProcess],msgCnt[nowProcess],strname[nowProcess][SendEnum]);m_SemaphoreReceive=CreateSemaphore(NULL,0,msgCnt[nowProcess],strname[nowProcess][ReceiveEnum]);//設(shè)置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()函數(shù)實(shí)現(xiàn)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("打開共享內(nèi)存失敗"));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()函數(shù)實(shí)現(xiàn)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("本進(jìn)程郵箱

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論