版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第4章 IOCP與可伸縮網(wǎng)絡(luò)程序,IOCP(I/O completion port,I/O完成端口)是伸縮性最好的一種I/O模型。,網(wǎng)絡(luò)通信編程技術(shù)與應(yīng)用,4.1 完成端口I/O模型,WinSock完成端口I/O模型,一般是用在大型的服務(wù)程序里面,他的效率和功能是最強(qiáng)大的。如果你的服務(wù)程序需要管理幾百甚至上千個(gè)Socket(海量連接)的話,如Apache,游戲服務(wù)器等,你應(yīng)該采用完成端口I/O模型。 采用完成端口的好處是,操作系統(tǒng)的內(nèi)部重疊機(jī)制可以保證大量的網(wǎng)絡(luò)請(qǐng)求都被服務(wù)器處理,而不是像WSAAsyncSelect 和WSAEventSelect的那樣對(duì)并發(fā)的網(wǎng)絡(luò)請(qǐng)求有限制。 “完成端口模型
2、是我最喜愛(ài)的一種模型。雖然其實(shí)現(xiàn)比較復(fù)雜(其實(shí)我覺(jué)得它的實(shí)現(xiàn)比用事件通知實(shí)現(xiàn)的重疊I/O簡(jiǎn)單多了),但其效率是驚人的。我在T公司的時(shí)候曾經(jīng)幫同事寫過(guò)一個(gè)郵件服務(wù)器的性能測(cè)試程序,用的就是完成端口模型。結(jié)果表明,完成端口模型在多連接(成千上萬(wàn))的情況下,僅僅依靠一兩個(gè)輔助線程,就可以達(dá)到非常高的吞吐量?!?一個(gè)IT人員的話.,不同I/O模式的性能測(cè)試結(jié)果:,Windows網(wǎng)絡(luò)編程模式有好幾種,他們各有特點(diǎn),實(shí)現(xiàn)起來(lái)復(fù)雜程度各不相同,適用范圍也不一樣。下圖是Network Programming for Microsoft Windows 2nd 一書中對(duì)不同模式的一個(gè)性能測(cè)試結(jié)果。服務(wù)器采用Pe
3、ntium 4 1.7 GHz Xeon的CPU,768M內(nèi)存;客戶端有3臺(tái)PC,配置分別是Pentium 2 233MHz ,128 MB 內(nèi)存,Pentium 2 350 MHz ,128 MB內(nèi)存,Itanium 733 MHz ,1 GB內(nèi)存。,結(jié)果分析大家可以看到:服務(wù)器,勿庸置疑,肯定是完成端口模式。那么客戶端呢,當(dāng)然也可以采用完成端口,但是不同模式是在不同的操作系統(tǒng)下支持的,看下圖:,完成端口在Windows 98下是不支持的。關(guān)鍵的一點(diǎn),客戶端程序不是用來(lái)進(jìn)行大規(guī)模網(wǎng)絡(luò)響應(yīng)的,客戶端的主要工作應(yīng)該是進(jìn)行諸如圖形運(yùn)算等非網(wǎng)絡(luò)方面的任務(wù)。所以,強(qiáng)烈推薦大家使用WSAAsyncSel
4、ect/ WSAEvevtSelect模式實(shí)現(xiàn)客戶端,因?yàn)樗鼘?shí)現(xiàn)起來(lái)比較直接和容易,而且他完全可以滿足客戶端編程的需求。,從本質(zhì)上說(shuō),完成端口模型要求我們創(chuàng)建一個(gè)Wi n 3 2完成端口對(duì)象,通過(guò)指定數(shù)量的線程,對(duì)重疊I / O請(qǐng)求進(jìn)行管理,以便為已經(jīng)完成的重疊I / O請(qǐng)求提供服務(wù)。 要注意: 所謂“完成端口”,實(shí)際是Wi n 3 2、 Windows NT以及Windows 2000采用的一種I / O構(gòu)造機(jī)制. 使用這種模型之前,首先要?jiǎng)?chuàng)建一個(gè)I / O完成端口對(duì)象,用它面向任意數(shù)量的套接字句柄,管理多個(gè)I / O請(qǐng)求。 IOCP只不過(guò)是用來(lái)進(jìn)行讀寫操作,和文件I/O有些類似。,實(shí)現(xiàn)過(guò)程
5、:,以下,分為以下幾步來(lái)說(shuō)明完成端口模型: 1。函數(shù) 2。常見(jiàn)問(wèn)題 3。步驟 4。例程,函數(shù),我們?cè)谕瓿啥丝谀P拖聲?huì)使用到的最重要的兩個(gè)函數(shù)是: (1) CreateIoCompletionPort (2) GetQueuedCompletionStatus,(1) CreateIoCompletionPort函數(shù),CreateIoCompletionPort 的作用是:創(chuàng)建一個(gè)完成端口對(duì)象;把一個(gè)IO句柄和完成端口關(guān)聯(lián)起來(lái)。 HANDLE CreateIoCompletionPort ( HANDLE FileHandle, /* handle to file*/ HANDLE Existi
6、ngCompletionPort, /* handle to I/O completion port*/ ULONG_PTR CompletionKey, /* completion key*/ DWORD NumberOfConcurrentThreads /* number of threads to execute concurrently*/ );,創(chuàng)建完成端口,通??梢允褂靡韵潞?jiǎn)單的代碼創(chuàng)建完成端口對(duì)象,獲得完成端口的句柄: HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0
7、);,0表示系統(tǒng)允許的線程數(shù)量與處理器一樣多。 但經(jīng)驗(yàn)給我們一個(gè)公式: 線程數(shù) = CPU數(shù) * 2 + 2,獲得CPU數(shù)量的方法: SYSTEM_INFO sysinfo; GetSystemInfo(,HANDLE CompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, sysinfo.dwNumberOfProcessors*2+2 );,把一個(gè)IO句柄和完成端口關(guān)聯(lián)起來(lái),這里的句柄是一個(gè)socket 句柄,CreateIoCompletionPort( (HANDLE)sClient, Complet
8、ionPort, (DWORD)PerHandleData, 0); 第一個(gè)參數(shù)是句柄,可以是文件句柄、SOCKET句柄。第二個(gè)就是我們上面創(chuàng)建出來(lái)的完成端口對(duì)象句柄,這里就把sClient和CompletionPort兩個(gè)東西關(guān)聯(lián)在一起了。第三個(gè)參數(shù)很關(guān)鍵,叫做PerHandleData(句柄惟一數(shù)據(jù)),就是對(duì)應(yīng)于每個(gè)句柄的數(shù)據(jù)塊。我們可以使用這個(gè)參數(shù)在后面取到與這個(gè)SOCKET對(duì)應(yīng)的任意類型的數(shù)據(jù),通常是一個(gè)指針。最后一個(gè)參數(shù)給0,表示系統(tǒng)允許的線程數(shù)量與處理器一樣多.,(2) GetQueuedCompletionStatus函數(shù),BOOL GetQueuedCompletionStat
9、us( HANDLE CompletionPort, / handle to completion port LPDWORD lpNumberOfBytes, / bytes transferred PULONG_PTR lpCompletionKey, / file completion key LPOVERLAPPED *lpOverlapped, / buffer DWORD dwMilliseconds / optional timeout value ); The function attempts to dequeue an I/O completion packet from a
10、 specified I/O completion port. If there is no completion packet queued, the function waits for a pending I/O operation associated with the completion port to complete.作用就是取得完成端口的結(jié)果。,從完成端口中取得結(jié)果,第一個(gè)參數(shù)是完成端口第二個(gè)參數(shù)是表明這次的操作傳遞了多少個(gè)字節(jié)的數(shù)據(jù)第三個(gè)是OUT類型的參數(shù),就是前面CreateIoCompletionPort傳進(jìn)去的單句柄數(shù)據(jù),這里就是前面的SOCKET句柄以及與之相對(duì)應(yīng)的
11、數(shù)據(jù),(這里操作系統(tǒng)給我們返回,讓我們不用自己去做列表查詢等操作了)。第四個(gè)參數(shù)就是進(jìn)行IO操作的結(jié)果,是我們?cè)谕哆f WSARecv / WSASend 等操作時(shí)傳遞進(jìn)去的,(這里操作系統(tǒng)做好準(zhǔn)備后,給我們返回了。非常省事?。?我感覺(jué)完成端口就是操作系統(tǒng)為我們包裝了很多重疊IO的不爽的地方,讓我們可以更方便的去使用。,常見(jiàn)問(wèn)題,a、什么是句柄惟一數(shù)據(jù)(PerHandleData)和單IO數(shù)據(jù)(PerIOData) 句柄惟一數(shù)據(jù),即單句柄數(shù)據(jù)就是和句柄對(duì)應(yīng)的數(shù)據(jù),像socket句柄,文件句柄這種東西。 單IO數(shù)據(jù),就是對(duì)應(yīng)于每次的IO操作的數(shù)據(jù)。例如每次的WSARecv/WSASend等 其實(shí)我
12、覺(jué)得PER是每次的意思,翻譯成每個(gè)句柄數(shù)據(jù)和每次IO數(shù)據(jù)還比較清晰一點(diǎn)。在完成端口中,單句柄數(shù)據(jù)直接通過(guò)GetQueuedCompletionStatus 返回,省去了我們自己做容器去管理。單IO數(shù)據(jù)也容許我們自己擴(kuò)展OVERLAPPED結(jié)構(gòu),所以,在這里所有與應(yīng)用邏輯有關(guān)的東西都可以在此擴(kuò)展。,b、如何判斷客戶端的斷開(kāi)。我們要處理幾種情況: 1) 如果客戶端調(diào)用了closesocket,就可以這樣判斷他的斷開(kāi): if(0 = GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, 。)if(BytesTransferred =
13、 0) / 客戶端斷開(kāi),釋放資源 2)如果是客戶端直接退出,那就會(huì)出現(xiàn)64錯(cuò)誤,指定的網(wǎng)絡(luò)名不可再用。這種情況我們也要處理的: if(0 = GetQueuedCompletionStatus(。) if( (GetLastError() = WAIT_TIMEOUT) | (GetLastError() = ERROR_NETNAME_DELETED) ) / 客戶端斷開(kāi),釋放資源 ,實(shí)現(xiàn)步驟,一個(gè)完成端口大概的處理流程: 1:創(chuàng)建一個(gè)完成端口。 2:創(chuàng)建一個(gè)線程A。 3:A線程循環(huán)調(diào)用GetQueuedCompletionStatus()函數(shù)來(lái)得到IO操作結(jié)果,這個(gè)函數(shù)是個(gè)阻塞函數(shù)。 4:
14、主線程循環(huán)里調(diào)用accept等待客戶端連接上來(lái)。 5:主線程里accept返回新連接建立以后,把這個(gè)新的套接字句柄用CreateIoCompletionPort關(guān)聯(lián)到完成端口,然后發(fā)出一個(gè)異步的WSASend或者WSARecv調(diào)用,因?yàn)槭钱惒胶瘮?shù),WSASend/WSARecv會(huì)馬上返回,實(shí)際的發(fā)送或者接收數(shù)據(jù)的操作由WINDOWS系統(tǒng)去做。 6:主線程繼續(xù)下一次循環(huán),阻塞在accept這里等待客戶端連接。 7:WINDOWS系統(tǒng)完成WSASend或者WSArecv的操作,把結(jié)果發(fā)到完成端口。 8:A線程里的GetQueuedCompletionStatus()馬上返回,并從完成端口取得剛完成
15、的WSASend/WSARecv的結(jié)果。 9:在A線程里對(duì)這些數(shù)據(jù)進(jìn)行處理(如果處理過(guò)程很耗時(shí),需要新開(kāi)線程處理),然后接著發(fā)出WSASend/WSARecv,并繼續(xù)下一次循環(huán)阻塞在GetQueuedCompletionStatus()這里。,其中紅線表示是WINDOWS系統(tǒng)進(jìn)行的處理,不需要我們程序干預(yù)。,可創(chuàng)建多個(gè)線程,應(yīng)用舉例,1。見(jiàn)completionIO server工程 2。見(jiàn)IOCPDemo工程,歸根到底概括完成端口模型一句話:,我們不停地向套接字發(fā)出異步的WSASend/ WSARecv IO操作,具體的IO處理過(guò)程由WINDOWS系統(tǒng)完成,WINDOWS系統(tǒng)完成實(shí)際的IO處理后,把結(jié)果送到完成端口上(如果有多個(gè)IO都完成了,那么就在完成端口那里排成一個(gè)隊(duì)列)。我們?cè)诹硗庖粋€(gè)線程里從完成端口不斷地取出IO操作結(jié)果,然后根據(jù)需要再發(fā)出WSASend/WSARecvIO操作。,注意:,如果你不是做大型的服務(wù)程序的話,其他I/O模型就夠了。,開(kāi)發(fā)建議:,1. 客戶機(jī)的開(kāi)發(fā) 建議采用重疊I/O或WSAEventSelect模型,以便在一定程度上提升性能。Windows為基礎(chǔ)的應(yīng)用程序,要進(jìn)行窗
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年宜賓國(guó)企招聘集團(tuán)董事長(zhǎng)機(jī)會(huì)難得點(diǎn)擊報(bào)名備考題庫(kù)及一套參考答案詳解
- 2026年中國(guó)廣核集團(tuán)有限公司招聘?jìng)淇碱}庫(kù)及答案詳解一套
- 2026年中山市教體系統(tǒng)第一期公開(kāi)招聘事業(yè)單位人員117人備考題庫(kù)及答案詳解1套
- 2026年中電金信數(shù)字科技集團(tuán)股份有限公司招聘?jìng)淇碱}庫(kù)及參考答案詳解1套
- 人工智能在合規(guī)風(fēng)險(xiǎn)識(shí)別中的應(yīng)用-第2篇
- 2026年中煤江南建設(shè)發(fā)展集團(tuán)有限公司特種工程分公司招聘?jìng)淇碱}庫(kù)及答案詳解參考
- 餐飲場(chǎng)所安全培訓(xùn)課件
- 餐飲商戶開(kāi)業(yè)安全培訓(xùn)課件
- 2026年上海市青浦區(qū)教育系統(tǒng)公開(kāi)招聘高端教育人才(管理方向)備考題庫(kù)及參考答案詳解一套
- 銀行服務(wù)智能化升級(jí)路徑-第1篇
- 2025年鄭州工業(yè)應(yīng)用技術(shù)學(xué)院馬克思主義基本原理概論期末考試模擬試卷
- 2026年七年級(jí)歷史上冊(cè)期末考試試卷及答案(共六套)
- 2025年六年級(jí)上冊(cè)道德與法治期末測(cè)試卷附答案(完整版)
- 附件二;吊斗安全計(jì)算書2.16
- 2025年全載錄丨Xsignal 全球AI應(yīng)用行業(yè)年度報(bào)告-
- 雨課堂在線學(xué)堂《西方哲學(xué)-從古希臘哲學(xué)到晚近歐陸哲學(xué)》單元考核測(cè)試答案
- IPC7711C7721C-2017(CN)電子組件的返工修改和維修(完整版)
- 學(xué)堂在線 雨課堂 學(xué)堂云 研究生學(xué)術(shù)與職業(yè)素養(yǎng)講座 章節(jié)測(cè)試答案
- 離婚協(xié)議書下載電子版完整離婚協(xié)議書下載三篇
- 磨床設(shè)備點(diǎn)檢表
- LS/T 8008-2010糧油倉(cāng)庫(kù)工程驗(yàn)收規(guī)程
評(píng)論
0/150
提交評(píng)論