青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

面對現(xiàn)實,超越自己
逆水行舟,不進(jìn)則退
posts - 269,comments - 32,trackbacks - 0

      完成端口聽起來好像很神秘和復(fù)雜,其實并沒有想象的那么難。這方面的文章在論壇上能找到的我差不多都看過,寫得好點的就是CSDN.NET上看到的一組系列文章,不過我認(rèn)為它只是簡單的翻譯了一下Network Programming for Microsoft Windows 2nd 中的相關(guān)內(nèi)容,附上的代碼好像不是原書中的,可能是另一本外文書里的。我看了以后,覺得還不如看原版的更容易理解。所以在我的開始部分,我主要帶領(lǐng)初學(xué)者理解一下完成端口的有關(guān)內(nèi)容,是我開發(fā)的經(jīng)驗,其他的請參考原書的相關(guān)內(nèi)容。
采用完成端口的好處是,操作系統(tǒng)的內(nèi)部重疊機(jī)制可以保證大量的網(wǎng)絡(luò)請求都被服務(wù)器處理,而不是像WSAAsyncSelect 和WSAEventSelect的那樣對并發(fā)的網(wǎng)絡(luò)請求有限制,這一點從上一章的測試表格中可以清楚的看出。
完成端口就像一種消息通知的機(jī)制,我們創(chuàng)建一個線程來不斷讀取完成端口狀態(tài),接收到相應(yīng)的完成通知后,就進(jìn)行相應(yīng)的處理。其實感覺就像 WSAAsyncSelect一樣,不過還是有一些的不同。比如我們想接收消息,WSAAsyncSelect會在消息到來的時候直接通知Windows 消息循環(huán),然后就可以調(diào)用WSARecv來接收消息了;而完成端口則首先調(diào)用一個WSARecv表示程序需要接收消息(這時可能還沒有任何消息到來),但是只有當(dāng)消息來的時候WSARecv才算完成,用戶就可以處理消息了,然后再調(diào)用一個WSARecv表示等待下一個消息,如此不停循環(huán),我想這就是完成端口的最大特點吧。
Per-handle Data 和 Per-I/O Operation Data 是兩個比較重要的概念,Per-handle Data用來把客戶端數(shù)據(jù)和對應(yīng)的完成通知關(guān)聯(lián)起來,這樣每次我們處理完成通知的時候,就能知道它是哪個客戶端的消息,并且可以根據(jù)客戶端的信息作出相應(yīng)的反應(yīng),我想也可以理解為Per-Client handle Data吧。Per-I/O Operation Data則不同,它記錄了每次I/O通知的信息,比如接收消息時我們就可以從中讀出消息的內(nèi)容,也就是和I/O操作有關(guān)的信息都記錄在里面了。當(dāng)你親手實現(xiàn)完成端口的時候就可以理解他們的不同和用途了。
CreateIoCompletionPort函數(shù)中有個參數(shù)NumberOfConcurrentThreads,完成端口編程里有個概念Worker Threads。這里比較容易引起混亂,NumberOfConcurrentThreads需要設(shè)置多少,又需要創(chuàng)建多少個Worker Threads才算合適?NumberOfConcurrentThreads的數(shù)目和CPU數(shù)量一樣最好,因為少了就沒法利用多CPU的優(yōu)勢,而多了則會因為線程切換造成性能下降。Worker Threads的數(shù)量是不是也要一樣多呢,當(dāng)然不是,它的數(shù)量取決于應(yīng)用程序的需要。舉例來說,我們在Worker Threads里進(jìn)行消息處理,如果這個過程中有可能會造成線程阻塞,那如果我們只有一個Worker Thread,我們就不能很快響應(yīng)其他客戶端的請求了,而只有當(dāng)這個阻塞操作完成了后才能繼續(xù)處理下一個完成消息。但是如果我們還有其他的Worker Thread,我們就能繼續(xù)處理其他客戶端的請求,所以到底需要多少的Worker Thread,需要根據(jù)應(yīng)用程序來定,而不是可以事先估算出來的。如果工作者線程里沒有阻塞操作,對于某些情況來說,一個工作者線程就可以滿足需要了。

===========================================================

“完成端口”模型是迄今為止最為復(fù)雜的—種I/O模型。然而。假若—個應(yīng)用程序同時需要管理為數(shù)眾多的套接字,那么采用這種模型。往往可以達(dá)到最佳的系統(tǒng)性能,然而不幸的是,該模型只適用于以下操作系統(tǒng)(微軟的)Windows NTWindows 2000操作系統(tǒng)。因其設(shè)計的復(fù)雜性,只有在你的應(yīng)用程序需要同時管理數(shù)百乃至上千個套接字的時候、而且希望隨著系統(tǒng)內(nèi)安裝的CPU數(shù)量的增多、應(yīng)用程序的性能也可以線性提升,才應(yīng)考慮采用“完成端口”模型。要記住的一個基本準(zhǔn)則是,假如要為Windows NTwindows 2000開發(fā)高性能的服務(wù)器應(yīng)用,同時希望為大量套接字I/O請求提供服務(wù)(Web服務(wù)器便是這方面的典型例子),那么I/O完成端口模型便是最佳選擇.

    從本質(zhì)上說,完成端口模型要求我們創(chuàng)建一個Win32完成端口對象,通過指定數(shù)量的線程對重疊I/O請求進(jìn)行管理。以便為已經(jīng)完成的重疊I/O請求提供服務(wù)。要注意的是。所謂“完成端口”,實際是Win32Windows NT以及windows 2000采用的一種I/O構(gòu)造機(jī)制,除套接字句柄之外,實際上還可接受其他東西。然而,本節(jié)只打算講述如何使用套接字句柄,來發(fā)揮完成端口模型的巨大威力。使用這種模型之前,首先要創(chuàng)建一個I/O完成端口對象,用它面向任意數(shù)量的套接字句柄。管理多個I/O請求。要做到這—點,需要調(diào)用CreateIoCompletionPort函數(shù)。該函數(shù)定義如下  

HANDLE CreateIoCompletionPort(

                              HANDLE FileHandle,

                              HANDLE ExistingCompletionPort,

                              DWORD CompletionKey,

                              DWORD  NumberOfConcurrentThreads

                              );

在我們深入探討其中的各個參數(shù)之前,首先要注意意該函數(shù)實際用于兩個明顯有別的目的:

    ■用于創(chuàng)建—個完成端口對象。

    ■將一個句柄同完成端口關(guān)聯(lián)到一起。

    最開始創(chuàng)建—個完成端口的時候,唯一感興趣的參數(shù)便是NumberOfConcurrentThreads 并發(fā)線程的數(shù)量);前面三個參數(shù)都會被忽略。NumberOfConcurrentThreads 參數(shù)的特殊之處在于.它定義了在一個完成端口上,同時允許執(zhí)行的線程數(shù)量。理想情況下我們希望每個處理器各自負(fù)責(zé)—個線程的運行,為完成端口提供服務(wù),避免過于頻繁的線程“場景”切換。若將該參數(shù)設(shè)為0,說明系統(tǒng)內(nèi)安裝了多少個處理器,便允許同時運行多少個線程!可用下述代碼創(chuàng)建一個I/O完成端口:

CompetionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0)

    該語加的作用是返問一個句柄.在為完成端口分配了—個套接字句柄后,用來對那個端

口進(jìn)行標(biāo)定(引用)

  

 1.工作者線程與完成端口

    成功創(chuàng)建一個完成端口后,便可開始將套接字句柄與對象關(guān)聯(lián)到一起。但在關(guān)聯(lián)套接字之前、首先必須創(chuàng)建—個或多個“工作者線程”,以便在I/O請求投遞給完成端口對象后。為完成端口提供服務(wù)。在這個時候,大家或許會覺得奇怪、到底應(yīng)創(chuàng)建多少個線程。以便為完成端口提供服務(wù)呢?這實際正是完成端口模型顯得頗為“復(fù)雜”的—個方面, 因為服務(wù)I/O請求所需的數(shù)量取決于應(yīng)用程序的總體設(shè)計情況。在此要記住的—個重點在于,在我們調(diào)用CreateIoComletionPort時指定的并發(fā)線程數(shù)量,與打算創(chuàng)建的工作者線程數(shù)量相比,它們代表的并非同—件事情。早些時候,我們曾建議大家用CreateIoCompletionPort函數(shù)為每個處理器都指定一個線程(處理器的數(shù)量有多少,便指定多少線程)以避免由于頻繁的線程“場景”交換活動,從而影響系統(tǒng)的整體性能。CreateIoCompletionPort函數(shù)的NumberofConcurrentThreads參數(shù)明確指示系統(tǒng):  在一個完成端口上,一次只允許n個工作者線程運行。假如在完成端門上創(chuàng)建的工作者線程數(shù)量超出n個.那么在同一時刻,最多只允許n個線程運行。但實際上,在—段較短的時間內(nèi),系統(tǒng)有可能超過這個值。但很快便會把它減少至事先在CreateIoCompletionPort函數(shù)中設(shè)定的值。那么,為何實際創(chuàng)建的工作者線程數(shù)最有時要比CreateIoCompletionPort函數(shù)設(shè)定的多—些呢?這樣做有必要嗎?如先前所述。這主要取決于應(yīng)用程序的總體設(shè)計情況,假設(shè)我們的工作者線程調(diào)用了一個函數(shù),比如Sleep()或者WaitForSingleobject(),但卻進(jìn)入了暫停(鎖定或掛起)狀態(tài)、那么允許另—個線程代替它的位置。換行之,我們希望隨時都能執(zhí)行盡可能多的線程;當(dāng)然,最大的線程數(shù)量是事先在CreateIoCompletonPort調(diào)用里設(shè)定好的。這樣—來。假如事先預(yù)料到自己的線程有可能暫時處于停頓狀態(tài),那么最好能夠創(chuàng)建比CreateIoCompletionPortNumberofConcurrentThreads參數(shù)的值多的線程.以便到時候充分發(fā)揮系統(tǒng)的潛力。—旦在完成端口上擁有足夠多的工作者線程來為I/O請求提供服務(wù),便可著手將套接字句柄同完成端口關(guān)聯(lián)到一起。這要求我們在—個現(xiàn)有的完成端口上調(diào)用CreateIoCompletionPort函數(shù),同時為前三個參數(shù): FileHandle,ExistingCompletionPortCompletionKey——提供套接字的信息。其中,FileHandle參數(shù)指定—個要同完成端口關(guān)聯(lián)在—一起的套接字句柄。

    ExistingCompletionPort參數(shù)指定的是一個現(xiàn)有的完成端口。CompletionKey(完成鍵)參數(shù)則指定要與某個特定套接字句柄關(guān)聯(lián)在—起的“單句柄數(shù)據(jù)”,在這個參數(shù)中,應(yīng)用程序可保存與—個套接字對應(yīng)的任意類型的信息。之所以把它叫作“單句柄數(shù)據(jù)”,是由于它只對應(yīng)著與那個套接字句柄關(guān)聯(lián)在—起的數(shù)據(jù)。可將其作為指向一個數(shù)據(jù)結(jié)構(gòu)的指針、來保存套接字句柄;在那個結(jié)構(gòu)中,同時包含了套接字的句柄,以及與那個套接字有關(guān)的其他信息。就象本章稍后還會講述的那樣,為完成端口提供服務(wù)的線程例程可通過這個參數(shù)。取得與其套字句柄有關(guān)的信息。

根據(jù)我們到目前為止學(xué)到的東西。首先來構(gòu)建—個基本的應(yīng)用程序框架。

程序清單89向人家闡述了如何使用完成端口模型。來開發(fā)—個回應(yīng)(或“反射’)服務(wù)器應(yīng)用

在這個程序中。我們基本上按下述步驟行事:

1)      創(chuàng)建一個完成端口。第四個參數(shù)保持為0,指定在完成端口上,每個處理器一次只允許執(zhí)行一個工作者線程。

2)      判斷系統(tǒng)內(nèi)到底安裝了多少個處理器。

3)      創(chuàng)建工作者線程,根據(jù)步驟2)得到的處理器信息,在完成端口上,為已完成的I/O請求提供服務(wù)。在這個簡單的例子中,我們?yōu)槊總€處理器都只創(chuàng)建—個工作者線程。這是出于事先已經(jīng)預(yù)計到,到時候不會有任何線程進(jìn)入“掛起”狀態(tài),造成由于線程數(shù)量的不足,而使處理器空閑的局面(沒有足夠的線程可供執(zhí)行)。調(diào)用CreateThread函數(shù)時,必須同時提供—個工作者線程,由線程在創(chuàng)建好執(zhí)行。本節(jié)稍后還會詳細(xì)討論線程的職責(zé)。

4)      準(zhǔn)備好—個監(jiān)聽套接字。在端口5150上監(jiān)聽進(jìn)入的連接請求。

5)      使用accept函數(shù),接受進(jìn)入的連接請求。

6)      創(chuàng)建—個數(shù)據(jù)結(jié)構(gòu),用于容納“單句柄數(shù)據(jù)”。  同時在結(jié)構(gòu)中存入接受的套接字句柄。

7)      調(diào)用CreateIoCompletionPort將自accept返回的新套接字句柄向完成端口關(guān)聯(lián)到  一起,通過完成鍵(CompletionKey)參數(shù),將但句柄數(shù)據(jù)結(jié)構(gòu)傳遞給CreateIoCompletionPort

8)      開始在已接受的連接上進(jìn)行I/O操作。在此,我們希望通過重疊I/O機(jī)制,在新建的套接字上投遞一個或多個異步WSARecvWSASend請求。這些I/O請求完成后,一個工作者線程會為I/O請求提供服務(wù),同時繼續(xù)處理未來的I/O請求,稍后便會在步驟3)指定的工作者例程中。體驗到這一點。

9)      重復(fù)步驟5)8)。直到服務(wù)器終止。

程序清單89  完成端口的建立

StartWinsock()

//步驟一,創(chuàng)建一個完成端口

CompletionPort=CreateIoCompletionPort(INVALI_HANDLE_VALUE,NULL,0,0);

//步驟二判斷有多少個處理器

GetSystemInfo(&SystemInfo);

//步驟三:根據(jù)處理器的數(shù)量創(chuàng)建工作線程,本例當(dāng)中,工作線程的數(shù)目和處理器數(shù)目是相同的

for(i  = 0; i < SystemInfo.dwNumberOfProcessers,i++){

HANDLE ThreadHandle;

//創(chuàng)建工作者線程,并把完成端口作為參數(shù)傳給線程

ThreadHandle=CreateThread(NULL,0

ServerWorkerThreadCompletionPort,

    0  &ThreadID);

//關(guān)閉線程句柄(僅僅關(guān)閉句柄,并非關(guān)閉線程本身)

CloseHandle(ThreadHandle);

}

//步驟四:創(chuàng)建監(jiān)聽套接字

Listen=WSASocket(AF_INET,S0CK_STREAM,0,NULL,

    WSA_FLAG_OVERLAPPED);

InternetAddr.sin_famlly=AF_INET;

InternetAddr.sin_addr.s_addr =  htonl(INADDR_ANY);

InternetAddr.sln_port  =  htons(5150);

bind(Listen,(PSOCKADDR)&InternetAddrsizeof(InternetAddr));

//準(zhǔn)備監(jiān)聽套接字

listen(Listen5);

while(TRUE){

//步驟五,接入Socket,并和完成端口關(guān)聯(lián)

Accept = WSAAccept(Listen,NULL,NULL,NULL,0);

//步驟六 創(chuàng)建一個perhandle結(jié)構(gòu),并和端口關(guān)聯(lián)

PerHandleData=(LPPER_HANDLE_DATA)GlobalAlloc(GPTRsizeof(PER_HANDLE_DATA));

printf("Socket  number  %d  connected\n",Accept);

PerHandleData->Socket=Accept;

//步驟七,接入套接字和完成端口關(guān)聯(lián)

CreateIoCompletionPort((HANDLE)Accept,

  CompletionPort,(DWORD)PerHandleData,0);

//步驟八

//開始進(jìn)行I/O操作,用重疊I/O發(fā)送一些WSASend()WSARecv()

WSARecv(...)

本文轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_458f4a2c0100nq44.html
posted on 2012-07-04 17:02 王海光 閱讀(536) 評論(0)  編輯 收藏 引用 所屬分類: C++
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情第五页| 欧美激情一区二区三区| 欧美在线www| 亚洲欧美激情视频在线观看一区二区三区 | 一区二区三区欧美在线| 一本色道久久综合亚洲精品不卡 | 最新日韩在线视频| 亚洲精品黄色| 亚洲中字黄色| 久久国产福利国产秒拍| 麻豆91精品| 日韩视频在线观看免费| 午夜精彩国产免费不卡不顿大片| 久久狠狠婷婷| 欧美国产日韩免费| 国产精品视频一| 亚洲高清在线播放| 亚洲网站视频| 免费成人在线观看视频| 亚洲精选一区二区| 久久久国产精品一区二区中文| 免费中文日韩| 国产精品久久久久久久久免费樱桃| 国产综合欧美在线看| 欲色影视综合吧| 亚洲欧美日韩国产中文在线| 欧美国产日韩二区| 亚洲无线一线二线三线区别av| 久久久久久69| 国产精品热久久久久夜色精品三区 | 久久躁狠狠躁夜夜爽| 欧美日韩一区二区三区在线视频| 国产曰批免费观看久久久| 亚洲图片欧洲图片av| 欧美激情1区2区3区| 亚洲一区二区网站| 欧美精品一区二区在线观看 | 亚洲女同在线| 亚洲国产合集| 欧美在线观看www| 欧美日本国产一区| 亚洲经典在线| 裸体一区二区| 欧美在线视频a| 欧美噜噜久久久xxx| 亚洲视频999| 亚洲深夜福利在线| 亚洲乱码精品一二三四区日韩在线| 羞羞色国产精品| 91久久精品美女高潮| 模特精品在线| 亚欧成人精品| 欧美一区二区视频观看视频| 黄色另类av| 亚洲激情在线激情| 国产精品黄视频| 米奇777超碰欧美日韩亚洲| 欧美日本中文字幕| 欧美激情bt| 亚洲深夜福利网站| 欧美一区二区日韩| 夜夜嗨av色综合久久久综合网| 欧美在线观看一二区| 中文av一区二区| 欧美日韩妖精视频| 亚洲深夜激情| 一本一本久久a久久精品综合妖精 一本一本久久a久久精品综合麻豆 | 欧美精品成人在线| 亚洲三级电影在线观看| 欧美高清在线视频观看不卡| 久久另类ts人妖一区二区| 亚洲电影免费在线| 最新亚洲视频| 国产精品久久久久久久久果冻传媒| 午夜在线精品偷拍| 午夜激情久久久| 在线观看91精品国产入口| 欧美国产精品专区| 欧美巨乳在线观看| 亚洲欧美日韩第一区| 欧美在线视频观看免费网站| 在线观看亚洲视频| 亚洲人成人77777线观看| 欧美三级午夜理伦三级中视频| 亚洲一区二区视频在线观看| 亚洲欧美bt| 亚洲成人自拍视频| 99国产精品国产精品毛片| 国产精品久久久久国产精品日日 | 久久综合一区二区三区| 99视频有精品| 欧美在线免费观看视频| 欧美一区二区视频免费观看| 裸体女人亚洲精品一区| 欧美日韩精品一区二区三区四区| 欧美在线视频免费播放| 欧美成人第一页| 久久精品国产一区二区三区免费看| 快she精品国产999| 亚洲欧美另类在线观看| 久久男女视频| 先锋影音久久| 欧美全黄视频| 欧美阿v一级看视频| 国产精品一区二区久久久久| 亚洲高清在线| 精品成人一区二区三区| 亚洲午夜一区二区| 亚洲免费观看高清在线观看 | 性欧美xxxx大乳国产app| 亚洲激情电影在线| 午夜在线视频观看日韩17c| 亚洲久久成人| 久久久久国产精品人| 亚洲自拍偷拍一区| 欧美高清不卡| 欧美成人激情视频| 国产一区二区三区直播精品电影| 一区电影在线观看| 亚洲久久视频| 欧美激情91| 亚洲国产成人在线视频| 1204国产成人精品视频| 久久精品国产久精国产思思| 亚洲欧美综合国产精品一区| 欧美日韩国产一中文字不卡 | 久久久久综合一区二区三区| 午夜精品影院| 国产精品三级久久久久久电影| 亚洲区中文字幕| 日韩视频在线永久播放| 男女视频一区二区| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲视频中文字幕| 欧美另类综合| 亚洲美女淫视频| 一本久久综合亚洲鲁鲁| 欧美经典一区二区三区| 最新亚洲一区| 亚洲视频在线观看| 国产精品极品美女粉嫩高清在线| av成人手机在线| 午夜在线精品偷拍| 国产亚洲精品久久久| 久久狠狠婷婷| 欧美国产日韩在线观看| 91久久国产综合久久91精品网站 | 国产精品一区二区久久国产| 亚洲欧美日韩国产| 久久一区视频| 亚洲人成在线播放| 欧美视频1区| 麻豆国产精品va在线观看不卡| 亚洲国产精品成人精品| 亚洲午夜日本在线观看| 久久国产精品第一页| 一区二区三区在线免费观看| 久热精品视频| 99国产欧美久久久精品| 欧美在线观看视频一区二区三区 | 日韩视频不卡中文| 欧美视频不卡| 久久久久久久精| 亚洲欧洲一区二区三区| 亚洲在线一区二区| 亚洲第一色中文字幕| 欧美日韩精品一区二区| 欧美一区二区在线| 亚洲国产精品成人va在线观看| 亚洲一二三四久久| 国内成+人亚洲| 欧美日韩在线播放三区四区| 久久精品国产999大香线蕉| 亚洲人成人77777线观看| 欧美一站二站| 日韩一级黄色大片| 怡红院精品视频在线观看极品| 欧美日韩免费观看一区三区| 久久精选视频| 中文亚洲视频在线| 欧美高清视频在线| 欧美一区二区三区成人| 亚洲精品一区二区三区在线观看| 国产欧美日韩免费看aⅴ视频| 欧美激情一区二区三区在线视频观看| 亚洲欧美日韩系列| 亚洲三级网站| 麻豆av一区二区三区| 香港久久久电影| 一本色道久久综合狠狠躁篇怎么玩 | 欧美freesex交免费视频| 亚洲午夜电影| 日韩视频中文字幕| 亚洲电影在线| 国内偷自视频区视频综合| 国产精品视频专区| 国产精品成人aaaaa网站| 欧美激情网友自拍| 欧美成人有码| 蜜臀91精品一区二区三区|