當(dāng)前位置:首頁(yè) > 物聯(lián)網(wǎng) > 《物聯(lián)網(wǎng)技術(shù)》雜志
[導(dǎo)讀]摘 要:介紹了Windows最復(fù)雜的內(nèi)核對(duì)象IOCP (I/O Completion Port輸入/輸出完成端口)的基本原理。利用完成端 口機(jī)制,應(yīng)用程序能夠?yàn)閿?shù)百上千的用戶(hù)服務(wù)。文章通過(guò)完成端口對(duì)象指定一定數(shù)量的線(xiàn)程,對(duì)重疊I/O請(qǐng)求進(jìn)行管理,從而 為已完成的重疊I/O請(qǐng)求提供服務(wù)。通過(guò)該模型編寫(xiě)的網(wǎng)絡(luò)服務(wù)應(yīng)用程序可以達(dá)到較好的性能。

引言

與計(jì)算機(jī)執(zhí)行的大多數(shù)其他操作相比,設(shè)備I/O是其中 最慢、最不可預(yù)測(cè)的操作之一。比如CPU從硬盤(pán)文件中讀寫(xiě)、 網(wǎng)絡(luò)讀取數(shù)據(jù)等,每一線(xiàn)程要等待I/O操作完成再執(zhí)行后續(xù) 的代碼。讓太多或者太少的服務(wù)器線(xiàn)程來(lái)處理線(xiàn)程,都可能 會(huì)導(dǎo)致性能問(wèn)題。使用異步設(shè)備I/O可以將請(qǐng)求交給設(shè)備的 驅(qū)動(dòng)程序去處理,應(yīng)用程序的線(xiàn)程可以執(zhí)行其他有用的任務(wù)。 這樣可以更好地使用資源并創(chuàng)建出更高效的應(yīng)用程序。

但是,隨著客戶(hù)端請(qǐng)求、退出的增加,會(huì)有許多的并發(fā) 線(xiàn)程并發(fā)執(zhí)行。由于這些線(xiàn)程都是可運(yùn)行狀態(tài),Windows內(nèi) 核會(huì)浪費(fèi)太多時(shí)間來(lái)進(jìn)行活動(dòng)線(xiàn)程的上下文切換,如不斷新 建和銷(xiāo)毀線(xiàn)程。Windows提供了 I/O完成端口機(jī)制可以很好 地解決上述問(wèn)題。

IOCP模型

當(dāng)我們創(chuàng)建一個(gè)I/O完成端口的時(shí)候,系統(tǒng)內(nèi)核實(shí)際上 會(huì)創(chuàng)建5個(gè)不同數(shù)據(jù)結(jié)構(gòu)。完成端口會(huì)將客戶(hù)請(qǐng)求加入到一 個(gè)公共的消息隊(duì)列中,然后應(yīng)用程序會(huì)創(chuàng)建一個(gè)線(xiàn)程池來(lái)處 理客戶(hù)的請(qǐng)求。當(dāng)設(shè)備與I/O完成端口相關(guān)聯(lián)后,系統(tǒng)會(huì)檢查 是否有與設(shè)備相關(guān)的一個(gè)I/O端口,若有則會(huì)將已完成的I/O 請(qǐng)求追加到消息隊(duì)列,并調(diào)用相關(guān)的工作線(xiàn)程來(lái)處理這個(gè)請(qǐng)求。 當(dāng)這個(gè)請(qǐng)求被處理完后,系統(tǒng)會(huì)通過(guò)一種機(jī)制通知客戶(hù),客戶(hù) 只需要取處理好的數(shù)據(jù)即可。圖1所示是一個(gè)完成端口模型 的結(jié)構(gòu)示意圖。

IOCP模型的使用

在實(shí)現(xiàn)異步通信機(jī)制的時(shí)候,一般要用到一個(gè)核心數(shù)據(jù) 結(jié)構(gòu)重疊(OVERLAPPED)結(jié)構(gòu)。OVERLAPPED結(jié)構(gòu)定義

如下:

typedef struct _OVERLAPPED

{

DWORD Internal ;//[out]保存已處理的I/O請(qǐng)求的錯(cuò)誤碼 DWORD InternalHigh ; //[out]異步I/O完成保存已傳輸?shù)淖?節(jié)數(shù)

DWORD Offset ; //[int]文件傳送的字節(jié)偏移量的低位字 DWORD OffsetHigh ;//[int]文件傳送的字節(jié)偏移量的高位字 HANDLE hEvent ; //[in]指定一個(gè)I/O操作完成后觸發(fā)的事件 [OVERLAPPED, *LPOVERLAPPED ;

OVERLAPPED結(jié)構(gòu)執(zhí)行兩個(gè)重要的功能:第一,它像 一把鑰匙,用以識(shí)別每一個(gè)目前正在進(jìn)行的overlapped操 作,比如在網(wǎng)絡(luò)發(fā)送和接收數(shù)據(jù)時(shí),都會(huì)用到WSASend()和 WSARecv。函數(shù),參數(shù)里面都會(huì)附帶一個(gè)重疊結(jié)構(gòu),這個(gè)重 疊結(jié)構(gòu)我們可以理解為一個(gè)網(wǎng)絡(luò)操作的ID號(hào),通過(guò)這個(gè)ID 號(hào)就可以區(qū)分是對(duì)哪個(gè)網(wǎng)絡(luò)進(jìn)行操作了;第二,它在你和系統(tǒng) 之間提供了一個(gè)共享區(qū)域,參數(shù)可以在該區(qū)域中雙向傳遞。

基于完成端口模型的應(yīng)用程序?qū)崿F(xiàn)

2.1創(chuàng)建I/O完成端口

_inHANDLEFileHandle,

_in_optHANDLEExistingCompletionPort,

_inULONG_PTRCompletionKey,

_inDWORDNumberOfConcurrentThreads);

PULONG_PTRlpCompletionKey,//當(dāng)文件I/O操作完成后,用于存放與之關(guān)聯(lián)的CK(套接字信息結(jié)構(gòu)體指針)

LPOVERLAPPED*lpOverlapped,//為調(diào)用IOCP機(jī)制所引用的OVERLAPPED結(jié)構(gòu)

DWORDdwMilliseconds,//用于指定調(diào)用者等待

該函數(shù)用于創(chuàng)建一個(gè)完成端口對(duì)象和將一個(gè)句柄同完成CP的時(shí)間

端口關(guān)聯(lián)在一起。在創(chuàng)建一個(gè)完成端口時(shí),前三個(gè)參數(shù)都會(huì)忽);

略,NumberOfConcurrentThreads參數(shù)指定允許有多少線(xiàn)程處于可運(yùn)行狀態(tài)。通常給NumberOfConcurrentThreads參數(shù)當(dāng)一^工作者線(xiàn)程從GetQueuedCompletionStatus調(diào)用中接收到I/O完成通知后,在lpCompletion和lpOverlapped參

設(shè)為0,那么I/O完成端口會(huì)使用默認(rèn)值,也就是允許并發(fā)執(zhí)數(shù)中,會(huì)包含一些必要的套接字信息。利用這些信息,可通

行的線(xiàn)程數(shù)量等于主機(jī)的CPU數(shù)量,避免額外的上下文切換。

過(guò)完成端口,繼續(xù)在一個(gè)套接字上進(jìn)行I/O處理。通過(guò)這些

代碼如下:hIOCP=CreateIoCompletionPort(INVALID_HANDLE

VALUE,NULL,0,0);

2.2工作者線(xiàn)程和完成端口

成功創(chuàng)建一個(gè)完成端口后,便可開(kāi)始將套接字句柄和對(duì)象關(guān)聯(lián)到一起。但是在關(guān)聯(lián)套接字之前,必須創(chuàng)建一個(gè)或多個(gè)工作者線(xiàn)程,以便在I/O請(qǐng)求投遞完成端口對(duì)象后,為完成端口提供服務(wù)。應(yīng)該創(chuàng)建多少個(gè)線(xiàn)程?在此要記住一個(gè)重點(diǎn),在調(diào)用CreateIoCompletionPort時(shí)指定的并發(fā)線(xiàn)程數(shù)量,與打算創(chuàng)建的線(xiàn)程池線(xiàn)程數(shù)量是有區(qū)別的。假如在完成端口上創(chuàng)建的工作者線(xiàn)程數(shù)量超過(guò)指定并發(fā)執(zhí)行的線(xiàn)性數(shù)量(這里設(shè)為n個(gè)),那么系統(tǒng)最多只允許n個(gè)線(xiàn)程運(yùn)行。因?yàn)槲覀冸S時(shí)都能執(zhí)行更多的線(xiàn)程,比如調(diào)用了函數(shù)Sleep或WaitForSingleObject使其處于暫停狀態(tài),就要用另外線(xiàn)程代替。為了充分發(fā)揮系統(tǒng)性能,一般設(shè)置為CPU的數(shù)量乘以2。

2.3完成端口與重疊I/O

創(chuàng)建好工作者線(xiàn)程后,調(diào)用GetQueuedCompletionStatus)函數(shù)讓句柄和完成端口相關(guān)聯(lián)起來(lái),進(jìn)行I/O請(qǐng)求處理。它將調(diào)用線(xiàn)程切換到睡眠狀態(tài),直到指定的完成端口的隊(duì)列中出現(xiàn)該請(qǐng)求。如以套接字句柄為基礎(chǔ),投遞數(shù)據(jù)發(fā)送和接收請(qǐng)求,會(huì)掃描完成端口的隊(duì)列里是否有網(wǎng)絡(luò)通信的請(qǐng)求存在(如讀取數(shù)據(jù)、發(fā)送數(shù)據(jù)等),一旦發(fā)現(xiàn)消息隊(duì)列中出現(xiàn)一項(xiàng)的時(shí)候,該完成端口會(huì)喚醒線(xiàn)性池中的一個(gè)線(xiàn)程。這個(gè)線(xiàn)程會(huì)得到已完成I/O項(xiàng)中的所有信息:

已傳輸?shù)淖止?jié)數(shù)、完成鍵以及OVERLAPPED結(jié)構(gòu)的地址。GetQueuedCompletionStatus()函數(shù)定義如下:

BOOLGetQueuedCompletionStatus(

HANDLECompletionPort,//指定的IOCP,該值由CreateIoCompletionPort函數(shù)創(chuàng)建

LPDWORDlpNumberOfBytes,//一次完成后的I/O操作所傳送數(shù)據(jù)的字節(jié)數(shù)

參數(shù),可獲得兩種重要的套接字?jǐn)?shù)據(jù)類(lèi)型:?jiǎn)尉浔鷶?shù)據(jù)以及單I/O操作數(shù)據(jù)。單I/O操作數(shù)據(jù)是CompletionKey(完成鍵)參數(shù)標(biāo)識(shí)的是某個(gè)特定的套接字句柄數(shù)據(jù),相當(dāng)于用一個(gè)標(biāo)志來(lái)綁定每一個(gè)I/O操作,這樣收到網(wǎng)絡(luò)操作完成的通知后,可以通過(guò)這個(gè)標(biāo)志來(lái)找出返回的數(shù)據(jù)對(duì)應(yīng)的I/O操作。該標(biāo)志可以定義如下:

typedefstruct_PER_IO_CONTEXT{

OVERLAPPEDm_Overlapped;//每一^重疊I/O網(wǎng)絡(luò)操作都要有一個(gè)

SOCKETm_sockAccept;//這個(gè)I/O操作所使用的Socket,每個(gè)連接的都是一樣的

WSABUFm_wsaBuf;//存儲(chǔ)數(shù)據(jù)的緩沖區(qū),用來(lái)給重疊操作傳遞參數(shù)的

charm_szBuffer[MAX_BUFFER_LEN];//對(duì)應(yīng)WSABUF里的緩沖區(qū)

OPERATION_TYPEm_OpType;//標(biāo)志這個(gè)重疊1/O操作是做什么的,例如Accept/Recv等}PER_IO_CONTEXT,*PPER_IO_CONTEXT;

該結(jié)構(gòu)關(guān)聯(lián)了與I/O操作的某些重要數(shù)據(jù)元素,例如完成I/O操作發(fā)送或接受請(qǐng)求的類(lèi)型m_OpType。每一個(gè)I/O操作對(duì)應(yīng)了響應(yīng)的PER_IO_CONTEXT,我們還要定義單句柄數(shù)據(jù)來(lái)管理句柄上的所有I/O請(qǐng)求,如在Socket上投遞了多個(gè)AcceptEx請(qǐng)求,該結(jié)構(gòu)定義如下:

typedefstruct_PER_SOCKET_CONTEXT{

SOCKETm_Socket;//每一個(gè)客戶(hù)端連接的Socket

SOCKADDR_INm_ClientAddr;//這個(gè)客戶(hù)端的地址

CArray<_PER_IO_CONTEXT*>m_arrayIoContext;//數(shù)組,所有客戶(hù)端IO操作的參數(shù),也就是說(shuō)對(duì)于每一個(gè)客戶(hù)端Socket是可以在上面同時(shí)投遞多個(gè)IO請(qǐng)求的

2014年/第3期物聯(lián)網(wǎng)技術(shù)61\}PER_SOCKET_CONTEXT,*PPER_SOCKET_CONTEXT;

2.4關(guān)閉IOCP

調(diào)用PostQueuedCompletionStatus函數(shù),向每個(gè)工作者線(xiàn)程都發(fā)送一個(gè)特殊的完成數(shù)據(jù)包??梢詥拘涯切┻€在等待完成端口但又沒(méi)有已完成的I/O請(qǐng)求,每個(gè)線(xiàn)程會(huì)對(duì)GetQueuedCompletionStatus的返回值進(jìn)行檢查,如果發(fā)現(xiàn)應(yīng)用程序正在終止,那么它就可以進(jìn)行清理工作并正常的退出。

3IOCP程序流程

該程序調(diào)用高性能特性的AcceptEx函數(shù)用來(lái)完成端口異步,取消了阻塞方式的Accept調(diào)用。我們知道,AcceptEx是在客戶(hù)端連入之前就把客戶(hù)端的Socket建立好了,而不需要像Accept那樣在客戶(hù)端連入之后,再去時(shí)間去建立Socket。統(tǒng)可能來(lái)不及為更多的并發(fā)客戶(hù)端現(xiàn)場(chǎng)準(zhǔn)備Socket。另外,相比Accept只能阻塞方式建立一個(gè)連入接口而AcceptEx可以同時(shí)在完成端口上投遞多個(gè)請(qǐng)求。圖2所示是其程序的整體流程圖。

基于完成端口模型的應(yīng)用程序?qū)崿F(xiàn)

4結(jié)語(yǔ)

采用I/O完成端口編寫(xiě)的服務(wù)應(yīng)用程序,經(jīng)過(guò)ProcessExplorer測(cè)試發(fā)現(xiàn)當(dāng)服務(wù)器收到3000個(gè)并發(fā)線(xiàn)程的時(shí)候CPU占有率約為4%,而采用了多個(gè)并發(fā)線(xiàn)程的客戶(hù)端程序CPU占有率約為12%。所以,如果預(yù)計(jì)到自己的服務(wù)器在任何給定的時(shí)間,都會(huì)為大量I/O請(qǐng)求提供服務(wù),便應(yīng)考慮使用I/O完成端口模型,從而獲得更好的性能。但是在編寫(xiě)基于完成端口的系統(tǒng)創(chuàng)建一個(gè)Socket的開(kāi)銷(xiāo)是相當(dāng)高了,用Accept的話(huà),系服務(wù)應(yīng)用程序時(shí),還應(yīng)注意重疊操作可確保按照應(yīng)用程序安排好的順序執(zhí)行。然而,不能確保從完成端口返回的完成通知也按照上述順序執(zhí)行。在對(duì)數(shù)據(jù)包有要求的時(shí)候,比如傳送大數(shù)據(jù)的時(shí)候,要注意這個(gè)順序。

20211120_6197d4b147075__基于完成端口模型的應(yīng)用程序實(shí)現(xiàn)

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀(guān)點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車(chē)的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車(chē)技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車(chē)工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車(chē)。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車(chē) 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶(hù)希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱(chēng),數(shù)字世界的話(huà)語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱(chēng)"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉