亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

        2014-04-04 13:58:29胡東紅杜光海賀偉毛守備
        物聯(lián)網(wǎng)技術(shù) 2014年3期
        關(guān)鍵詞:應(yīng)用程序

        胡東紅+杜光海+賀偉+毛守備

        摘 要:介紹了Windows最復(fù)雜的內(nèi)核對象IOCP(I/O Completion Port 輸入/輸出完成端口)的基本原理。利用完成端口機制,應(yīng)用程序能夠為數(shù)百上千的用戶服務(wù)。文章通過完成端口對象指定一定數(shù)量的線程,對重疊I/O請求進(jìn)行管理,從而為已完成的重疊I/O請求提供服務(wù)。通過該模型編寫的網(wǎng)絡(luò)服務(wù)應(yīng)用程序可以達(dá)到較好的性能。

        關(guān)鍵詞:完成端口;異步I/O;線程池;應(yīng)用程序

        中圖分類號:TP391 文獻(xiàn)標(biāo)識碼:A 文章編號:2095-1302(2014)03-0060-03

        0 引 言

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

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

        1 IOCP模型

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

        2 IOCP模型的使用

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

        typedef struct _OVERLAPPED

        {

        DWORD Internal;//[out] 保存已處理的I/O請求的錯誤碼

        DWORD InternalHigh;//[out] 異步I/O完成保存已傳輸?shù)淖止?jié)數(shù)

        DWORD Offset;//[int] 文件傳送的字節(jié)偏移量的低位字

        DWORD OffsetHigh;//[int] 文件傳送的字節(jié)偏移量的高位字

        HANDLE hEvent;//[in] 指定一個I/O操作完成后觸發(fā)的事件

        }OVERLAPPED,*LPOVERLAPPED;

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

        圖1 完成端口模型

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

        在使用這種模型之前,首先要創(chuàng)建一個I/O完成端口對象,用它面向任意數(shù)量的設(shè)備句柄,管理多個I/O請求,需要調(diào)用CreateIoCompletionPort()函數(shù),該函數(shù)定義如下:

        HANDLE WINAPI CreateIoCompletionPort(

        _in HANDLE FileHandle,

        _in_opt HANDLE ExistingCompletionPort,

        _in ULONG_PTR CompletionKey,

        _in DWORD NumberOfConcurrentThreads

        );

        該函數(shù)用于創(chuàng)建一個完成端口對象和將一個句柄同完成端口關(guān)聯(lián)在一起。在創(chuàng)建一個完成端口時,前三個參數(shù)都會忽略,NumberOfConcurrentThreads參數(shù)指定允許有多少線程處于可運行狀態(tài)。通常給NumberOfConcurrentThreads參數(shù)設(shè)為0,那么I/O完成端口會使用默認(rèn)值,也就是允許并發(fā)執(zhí)行的線程數(shù)量等于主機的CPU數(shù)量,避免額外的上下文切換。代碼如下:

        hIOCP=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);

        2.2 工作者線程和完成端口

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

        2.3 完成端口與重疊I/O

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

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

        BOOL GetQueuedCompletionStatus(

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

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

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

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

        DWORD dwMilliseconds,//用于指定調(diào)用者等待CP的時間

        );

        當(dāng)一個工作者線程從GetQueuedCompletionStatus調(diào)用中接收到I/O完成通知后,在lpCompletion和lpOverlapped參數(shù)中,會包含一些必要的套接字信息。利用這些信息,可通過完成端口,繼續(xù)在一個套接字上進(jìn)行I/O處理。通過這些參數(shù),可獲得兩種重要的套接字?jǐn)?shù)據(jù)類型:單句柄數(shù)據(jù)以及單I/O操作數(shù)據(jù)。單I/O操作數(shù)據(jù)是CompletionKey(完成鍵)參數(shù)標(biāo)識的是某個特定的套接字句柄數(shù)據(jù),相當(dāng)于用一個標(biāo)志來綁定每一個I/O操作,這樣收到網(wǎng)絡(luò)操作完成的通知后,可以通過這個標(biāo)志來找出返回的數(shù)據(jù)對應(yīng)的I/O操作。該標(biāo)志可以定義如下:

        typedef struct _PER_IO_CONTEXT{

        OVERLAPPED m_Overlapped; // 每一個重疊I/O

        網(wǎng)絡(luò)操作都要有一個

        SOCKET m_sockAccept; // 這個I/O操作所使用的

        Socket,每個連接的都是一樣的

        WSABUF m_wsaBuf; //存儲數(shù)據(jù)的緩沖區(qū),用來給

        重疊操作傳遞參數(shù)的

        char m_szBuffer[MAX_BUFFER_LEN]; // 對應(yīng)

        WSABUF里的緩沖區(qū)

        OPERATION_TYPE m_OpType; // 標(biāo)志這個重疊I/

        O操作是做什么的,例如Accept/Recv等

        } PER_IO_CONTEXT, *PPER_IO_CONTEXT;

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

        typedef struct _PER_SOCKET_CONTEXT{

        SOCKET m_Socket;// 每一個客戶端連接的Socket

        SOCKADDR_IN m_ClientAddr;// 這個客戶端的地址

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

        } PER_SOCKET_CONTEXT, *PPER_SOCKET_CONTEXT;

        2.4 關(guān)閉IOCP

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

        3 IOCP程序流程

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

        4 結(jié) 語

        采用I/O完成端口編寫的服務(wù)應(yīng)用程序,經(jīng)過Process Explorer測試發(fā)現(xiàn)當(dāng)服務(wù)器收到3 000個并發(fā)線程的時候CPU占有率約為4%,而采用了多個并發(fā)線程的客戶端程序CPU占有率約為12%。所以,如果預(yù)計到自己的服務(wù)器在任何給定的時間,都會為大量I/O請求提供服務(wù),便應(yīng)考慮使用I/O完成端口模型,從而獲得更好的性能。但是在編寫基于完成端口的服務(wù)應(yīng)用程序時,還應(yīng)注意重疊操作可確保按照應(yīng)用程序安排好的順序執(zhí)行。然而,不能確保從完成端口返回的完成通知也按照上述順序執(zhí)行。在對數(shù)據(jù)包有要求的時候,比如傳送大數(shù)據(jù)的時候,要注意這個順序。

        參 考 文 獻(xiàn)

        [1] RICHTER J,NASARRE C. Windows 核心編程[M].Fifth Edition,葛子敖,周靖,等,譯.北京:清華大學(xué)出版社,2008.

        [2] BEVERIDGE J,WIENER R.Wind32多線程程序設(shè)計[M].侯捷,譯.武漢:華中科技大學(xué)出版社,2006.

        [3] ANTHONY Jones, JIM Ohlund. Network programming for Microsoft Windows [M]. 北京: 清華大學(xué)出版社,2002.

        [4] 周鵬,黃燦,江楠. 完成端口模型的使用與分析[J]. 軟件, 2012(2): 37-38.

        [5] 林延君. 局域網(wǎng)企業(yè)信息安全系統(tǒng)的設(shè)計與實現(xiàn)[D]. 大連:大連理工大學(xué),2006.

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

        BOOL GetQueuedCompletionStatus(

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

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

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

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

        DWORD dwMilliseconds,//用于指定調(diào)用者等待CP的時間

        );

        當(dāng)一個工作者線程從GetQueuedCompletionStatus調(diào)用中接收到I/O完成通知后,在lpCompletion和lpOverlapped參數(shù)中,會包含一些必要的套接字信息。利用這些信息,可通過完成端口,繼續(xù)在一個套接字上進(jìn)行I/O處理。通過這些參數(shù),可獲得兩種重要的套接字?jǐn)?shù)據(jù)類型:單句柄數(shù)據(jù)以及單I/O操作數(shù)據(jù)。單I/O操作數(shù)據(jù)是CompletionKey(完成鍵)參數(shù)標(biāo)識的是某個特定的套接字句柄數(shù)據(jù),相當(dāng)于用一個標(biāo)志來綁定每一個I/O操作,這樣收到網(wǎng)絡(luò)操作完成的通知后,可以通過這個標(biāo)志來找出返回的數(shù)據(jù)對應(yīng)的I/O操作。該標(biāo)志可以定義如下:

        typedef struct _PER_IO_CONTEXT{

        OVERLAPPED m_Overlapped; // 每一個重疊I/O

        網(wǎng)絡(luò)操作都要有一個

        SOCKET m_sockAccept; // 這個I/O操作所使用的

        Socket,每個連接的都是一樣的

        WSABUF m_wsaBuf; //存儲數(shù)據(jù)的緩沖區(qū),用來給

        重疊操作傳遞參數(shù)的

        char m_szBuffer[MAX_BUFFER_LEN]; // 對應(yīng)

        WSABUF里的緩沖區(qū)

        OPERATION_TYPE m_OpType; // 標(biāo)志這個重疊I/

        O操作是做什么的,例如Accept/Recv等

        } PER_IO_CONTEXT, *PPER_IO_CONTEXT;

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

        typedef struct _PER_SOCKET_CONTEXT{

        SOCKET m_Socket;// 每一個客戶端連接的Socket

        SOCKADDR_IN m_ClientAddr;// 這個客戶端的地址

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

        } PER_SOCKET_CONTEXT, *PPER_SOCKET_CONTEXT;

        2.4 關(guān)閉IOCP

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

        3 IOCP程序流程

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

        4 結(jié) 語

        采用I/O完成端口編寫的服務(wù)應(yīng)用程序,經(jīng)過Process Explorer測試發(fā)現(xiàn)當(dāng)服務(wù)器收到3 000個并發(fā)線程的時候CPU占有率約為4%,而采用了多個并發(fā)線程的客戶端程序CPU占有率約為12%。所以,如果預(yù)計到自己的服務(wù)器在任何給定的時間,都會為大量I/O請求提供服務(wù),便應(yīng)考慮使用I/O完成端口模型,從而獲得更好的性能。但是在編寫基于完成端口的服務(wù)應(yīng)用程序時,還應(yīng)注意重疊操作可確保按照應(yīng)用程序安排好的順序執(zhí)行。然而,不能確保從完成端口返回的完成通知也按照上述順序執(zhí)行。在對數(shù)據(jù)包有要求的時候,比如傳送大數(shù)據(jù)的時候,要注意這個順序。

        參 考 文 獻(xiàn)

        [1] RICHTER J,NASARRE C. Windows 核心編程[M].Fifth Edition,葛子敖,周靖,等,譯.北京:清華大學(xué)出版社,2008.

        [2] BEVERIDGE J,WIENER R.Wind32多線程程序設(shè)計[M].侯捷,譯.武漢:華中科技大學(xué)出版社,2006.

        [3] ANTHONY Jones, JIM Ohlund. Network programming for Microsoft Windows [M]. 北京: 清華大學(xué)出版社,2002.

        [4] 周鵬,黃燦,江楠. 完成端口模型的使用與分析[J]. 軟件, 2012(2): 37-38.

        [5] 林延君. 局域網(wǎng)企業(yè)信息安全系統(tǒng)的設(shè)計與實現(xiàn)[D]. 大連:大連理工大學(xué),2006.

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

        BOOL GetQueuedCompletionStatus(

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

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

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

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

        DWORD dwMilliseconds,//用于指定調(diào)用者等待CP的時間

        );

        當(dāng)一個工作者線程從GetQueuedCompletionStatus調(diào)用中接收到I/O完成通知后,在lpCompletion和lpOverlapped參數(shù)中,會包含一些必要的套接字信息。利用這些信息,可通過完成端口,繼續(xù)在一個套接字上進(jìn)行I/O處理。通過這些參數(shù),可獲得兩種重要的套接字?jǐn)?shù)據(jù)類型:單句柄數(shù)據(jù)以及單I/O操作數(shù)據(jù)。單I/O操作數(shù)據(jù)是CompletionKey(完成鍵)參數(shù)標(biāo)識的是某個特定的套接字句柄數(shù)據(jù),相當(dāng)于用一個標(biāo)志來綁定每一個I/O操作,這樣收到網(wǎng)絡(luò)操作完成的通知后,可以通過這個標(biāo)志來找出返回的數(shù)據(jù)對應(yīng)的I/O操作。該標(biāo)志可以定義如下:

        typedef struct _PER_IO_CONTEXT{

        OVERLAPPED m_Overlapped; // 每一個重疊I/O

        網(wǎng)絡(luò)操作都要有一個

        SOCKET m_sockAccept; // 這個I/O操作所使用的

        Socket,每個連接的都是一樣的

        WSABUF m_wsaBuf; //存儲數(shù)據(jù)的緩沖區(qū),用來給

        重疊操作傳遞參數(shù)的

        char m_szBuffer[MAX_BUFFER_LEN]; // 對應(yīng)

        WSABUF里的緩沖區(qū)

        OPERATION_TYPE m_OpType; // 標(biāo)志這個重疊I/

        O操作是做什么的,例如Accept/Recv等

        } PER_IO_CONTEXT, *PPER_IO_CONTEXT;

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

        typedef struct _PER_SOCKET_CONTEXT{

        SOCKET m_Socket;// 每一個客戶端連接的Socket

        SOCKADDR_IN m_ClientAddr;// 這個客戶端的地址

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

        } PER_SOCKET_CONTEXT, *PPER_SOCKET_CONTEXT;

        2.4 關(guān)閉IOCP

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

        3 IOCP程序流程

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

        4 結(jié) 語

        采用I/O完成端口編寫的服務(wù)應(yīng)用程序,經(jīng)過Process Explorer測試發(fā)現(xiàn)當(dāng)服務(wù)器收到3 000個并發(fā)線程的時候CPU占有率約為4%,而采用了多個并發(fā)線程的客戶端程序CPU占有率約為12%。所以,如果預(yù)計到自己的服務(wù)器在任何給定的時間,都會為大量I/O請求提供服務(wù),便應(yīng)考慮使用I/O完成端口模型,從而獲得更好的性能。但是在編寫基于完成端口的服務(wù)應(yīng)用程序時,還應(yīng)注意重疊操作可確保按照應(yīng)用程序安排好的順序執(zhí)行。然而,不能確保從完成端口返回的完成通知也按照上述順序執(zhí)行。在對數(shù)據(jù)包有要求的時候,比如傳送大數(shù)據(jù)的時候,要注意這個順序。

        參 考 文 獻(xiàn)

        [1] RICHTER J,NASARRE C. Windows 核心編程[M].Fifth Edition,葛子敖,周靖,等,譯.北京:清華大學(xué)出版社,2008.

        [2] BEVERIDGE J,WIENER R.Wind32多線程程序設(shè)計[M].侯捷,譯.武漢:華中科技大學(xué)出版社,2006.

        [3] ANTHONY Jones, JIM Ohlund. Network programming for Microsoft Windows [M]. 北京: 清華大學(xué)出版社,2002.

        [4] 周鵬,黃燦,江楠. 完成端口模型的使用與分析[J]. 軟件, 2012(2): 37-38.

        [5] 林延君. 局域網(wǎng)企業(yè)信息安全系統(tǒng)的設(shè)計與實現(xiàn)[D]. 大連:大連理工大學(xué),2006.

        猜你喜歡
        應(yīng)用程序
        刪除Win10中自帶的應(yīng)用程序
        電腦報(2019年12期)2019-09-10 05:08:20
        谷歌禁止加密貨幣應(yīng)用程序
        Windows環(huán)境下基于棧和堆的應(yīng)用程序行為解析方法研究
        用好被忽視的Office應(yīng)用程序
        電腦迷(2014年12期)2014-04-29 00:44:03
        保護(hù)移動設(shè)備的安全
        關(guān)閉應(yīng)用程序更新提醒
        電腦迷(2012年15期)2012-04-29 17:09:47
        為軟件付費你準(zhǔn)備好了嗎?
        三星電子將開設(shè)應(yīng)用程序下載商店
        微軟軟件商店開始接受應(yīng)用程序
        啟動后提示MOM.EXE錯誤
        国产成人综合久久亚洲精品| 久久精品国产亚洲av试看| 亚洲日本高清一区二区| 97久久国产亚洲精品超碰热| 国产精品人妻一码二码尿失禁 | 亚洲av乱码二区三区涩涩屋| 无码视频在线观看| 又粗又大又黄又爽的免费视频| 精精国产xxxx视频在线播放器| 亚洲中字永久一区二区三区| 精品一区二区三区在线视频| 精品少妇人妻av一区二区| 日韩欧美亚洲中字幕在线播放| 久久久人妻一区精品久久久 | 日韩精品资源在线观看免费| 激情综合五月| 人妻少妇av中文字幕乱码| 免费一级黄色大片久久久| 国产自拍视频一区在线| 日韩一区二区三区无码影院| 狠狠色狠狠色综合日日不卡| 国产亚洲精品国看不卡| 国产精品亚洲一区二区三区在线| 影视av久久久噜噜噜噜噜三级| 中国年轻丰满女人毛茸茸| 亚洲美女av一区二区| 青草久久婷婷亚洲精品| 中文字幕av免费专区| 日日摸夜夜添夜夜添一区二区| 一区二区三区国产大片| 国产精品美女久久久免费| 欧美丰满熟妇aaaaa片| 国产欧美激情一区二区三区| 亚洲黄色av一区二区三区| 一本色道久久88精品综合| 国产在线91观看免费观看| 久久99久久久精品人妻一区二区| 亚洲av无码国产精品久久| 内射中出无码护士在线| 国产 无码 日韩| 成人偷拍自拍视频在线观看|