版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
實驗題目實驗?zāi)康恼莆沼绵]箱方式進行進程通信的方法,并通過設(shè)計實現(xiàn)簡單郵箱理解進程通信中的同步問題以及解決該問題的方法。實驗環(huán)境WindowsXPSP3實驗原理郵箱機制類似于日常使用的信箱。對于用戶而言使用起來比較方便,用戶只需使用send()向?qū)Ψ洁]箱發(fā)郵件receive()從自己郵箱取郵件,send()和receive()的內(nèi)部操作用戶無需關(guān)心。因為郵箱在內(nèi)存中實現(xiàn),其空間有大小限制。其實send()和receive()的內(nèi)部實現(xiàn)主要還是要解決生產(chǎn)者與消費者問題。實驗內(nèi)容進程通信的郵箱方式由操作系統(tǒng)提供形如send()和receive()的系統(tǒng)調(diào)用來支持,本實驗要求學(xué)生首先查找資料了解所選用操作系統(tǒng)平臺上用于進程通信的系統(tǒng)調(diào)用具體形式,然后使用該系統(tǒng)調(diào)用編寫程序進行進程間的通信,要求程序運行結(jié)果可以直觀地體現(xiàn)在界面上。在此基礎(chǔ)上查找所選用操作系統(tǒng)平臺上支持信號量機制的系統(tǒng)調(diào)用具體形式,運用生產(chǎn)者與消費者模型設(shè)計實現(xiàn)一個簡單的信箱,該信箱需要有創(chuàng)建、發(fā)信、收信、撤銷等函數(shù),至少能夠支持兩個進程互相交換信息,比較自己實現(xiàn)的信箱與操作系統(tǒng)本身提供的信箱,分析兩者之間存在的異同。Mutex和Semaphore區(qū)別在windows環(huán)境下兩者有著類似之處但不完全相同。Semaphore可以比喻成是一個銀行(臨界區(qū))有N人的服務(wù)窗口(最大允許同步進程數(shù)量),如果申請的客戶(進程)少于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可以被其他進程釋放在前面的例子中就是允許插隊,這樣會導(dǎo)致超過允許服務(wù)的進程上限共享內(nèi)存實現(xiàn)郵箱的數(shù)據(jù)結(jié)構(gòu)由于共享內(nèi)存的方法不直接提供隊列功能故采用循環(huán)隊列思想模擬緩沖區(qū),下面是共享內(nèi)存的頭部,用來存儲索引信息struct{DWORDMsgSize;//單個消息大小:字節(jié)數(shù)intMsgMaxCount;//消息的總數(shù)intMsgNum;//消息的個數(shù)intReadIndex;//可讀消息索引intWriteIndex;//可寫消息索引};“實時”顯示內(nèi)容的處理與內(nèi)存泄漏這個顯示消息的函數(shù)每隔50ms執(zhí)行一次,所以實際上是是查詢方式來實現(xiàn)實時顯示在此模式下可以發(fā)現(xiàn)一些被人遺忘的內(nèi)存釋放,我在實現(xiàn)這個函數(shù)時候發(fā)現(xià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ù)實現(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ù)實現(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ù)實現(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("本進程郵箱
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年度BIM模型在景觀設(shè)計中的應(yīng)用合同
- 《轉(zhuǎn)甲狀腺素蛋白在腫瘤研究中的進展》
- 《NURBS曲線插補實時前瞻控制方法的研究》
- 《基于區(qū)塊鏈遠(yuǎn)程醫(yī)療會診決策共識模型的研究》
- 2024年度IDC機房網(wǎng)絡(luò)設(shè)備租用合同
- 《城市低收入人群身體自尊與生活滿意度關(guān)系研究》
- 2024年安全型車庫門制造銷售合同
- 2024年建筑內(nèi)部承包合同
- 2024年瀘州大客車從業(yè)資格證考試試題
- 2024年銅仁經(jīng)營性道路旅客運輸駕駛員從業(yè)資格考試題庫
- 2024年企業(yè)數(shù)據(jù)存儲與安全服務(wù)合同
- 2022年北京市公務(wù)員錄用考試《行測》真題及答案解析
- 江蘇省泰興市2024-2025學(xué)年高三上學(xué)期期中考試語文試題(含答案)
- 家長會教學(xué)課件
- 律師事務(wù)所律師事務(wù)所風(fēng)險管理手冊
- 2024年消防宣傳月知識競賽考試題庫500題(含答案)
- 2024年典型事故案例警示教育手冊15例
- 高一歷史(中外歷史綱要上冊)期中測試卷及答案
- 20K607 防排煙及暖通防火設(shè)計審查與安裝
- 一氧化碳中毒培訓(xùn)課件
- 教案(餐巾折花)
評論
0/150
提交評論