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

隨筆 - 298  文章 - 377  trackbacks - 0
<2025年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

常用鏈接

留言簿(34)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

  歡迎閱讀此篇IOCP教程。我將先給出IOCP的定義然后給出它的實現方法,最后剖析一個Echo程序來為您撥開IOCP的謎云,除去你心中對IOCP的煩惱。OK,但我不能保證你明白IOCP的一切,但我會盡我最大的努力。以下是我會在這篇文章中提到的相關技術:
  I/O端口
  同步/異步
  堵塞/非堵塞
  服務端/客戶端
  多線程程序設計
  Winsock API 2.0

  在這之前,我曾經開發過一個項目,其中一塊需要網絡支持,當時還考慮到了代碼的可移植性,只要使用select,connect,accept,listen,send還有recv,再加上幾個#ifdef的封裝以用來處理Winsock和BSD套接字[socket]中間的不兼容性,一個網絡子系統只用了幾個小時很少的代碼就寫出來了,至今還讓我很回味。那以后很長時間也就沒再碰了。

  前些日子,我們策劃做一個網絡游戲,我主動承擔下網絡這一塊,想想這還不是小case,心里偷著樂啊。網絡游戲好啊,網絡游戲為成百上千的玩家提供了樂趣和令人著秘的游戲體驗,他們在線上互相戰斗或是加入隊伍去戰勝共同的敵人。我信心滿滿的準備開寫我的網絡,于是乎,發現過去的阻塞同步模式模式根本不能拿到一個巨量多玩家[MMP]的架構中去,直接被否定掉了。于是乎,就有了IOCP,如果能過很輕易而舉的搞掂IOCP,也就不會有這篇教程了。下面請諸位跟隨我進入正題。


什么是IOCP?
先讓我們看看對IOCP的評價
I/O完成端口可能是Win32提供的最復雜的內核對象。
[Advanced Windows 3rd] Jeffrey Richter
這是[IOCP]實現高容量網絡服務器的最佳方法。
[Windows Sockets2.0:Write Scalable Winsock Apps Using Completion Ports]
Microsoft Corporation
完成端口模型提供了最好的伸縮性。這個模型非常適用來處理數百乃至上千個套接字。
[Windows網絡編程2nd] Anthony Jones & Jim Ohlund
I/O completion ports特別顯得重要,因為它們是唯一適用于高負載服務器[必須同時維護許多連接線路]的一個技術。Completion ports利用一些線程,幫助平衡由I/O請求所引起的負載。這樣的架構特別適合用在SMP系統中產生的”scalable”服務器。
[Win32多線程程序設計] Jim Beveridge & Robert Wiener


看來我們完全有理由相信IOCP是大型網絡架構的首選。那IOCP到底是什么呢?

  微軟在Winsock2中引入了IOCP這一概念 。IOCP全稱I/O Completion Port,中文譯為I/O完成端口。IOCP是一個異步I/O的API,它可以高效地將I/O事件通知給應用程序。與使用select()或是其它異步方法不同的是,一個套接字[socket]與一個完成端口關聯了起來,然后就可繼續進行正常的Winsock操作了。然而,當一個事件發生的時候,此完成端口就將被操作系統加入一個隊列中。然后應用程序可以對核心層進行查詢以得到此完成端口。

  這里我要對上面的一些概念略作補充,在解釋[完成]兩字之前,我想先簡單的提一下同步和異步這兩個概念,邏輯上來講做完一件事后再去做另一件事就是同步,而同時一起做兩件或兩件以上事的話就是異步了。你也可以拿單線程和多線程來作比喻。但是我們一定要將同步和堵塞,異步和非堵塞區分開來,所謂的堵塞函數諸如accept(…),當調用此函數后,此時線程將掛起,直到操作系統來通知它,”HEY兄弟,有人連進來了”,那個掛起的線程將繼續進行工作,也就符合”生產者-消費者”模型。堵塞和同步看上去有兩分相似,但卻是完全不同的概念。大家都知道I/O設備是個相對慢速的設備,不論打印機,調制解調器,甚至硬盤,與CPU相比都是奇慢無比的,坐下來等I/O的完成是一件不甚明智的事情,有時候數據的流動率非常驚人,把數據從你的文件服務器中以Ethernet速度搬走,其速度可能高達每秒一百萬字節,如果你嘗試從文件服務器中讀取100KB,在用戶的眼光來看幾乎是瞬間完成,但是,要知道,你的線程執行這個命令,已經浪費了10個一百萬次CPU周期。所以說,我們一般使用另一個線程來進行I/O。重疊IO[overlapped I/O]是Win32的一項技術,你可以要求操作系統為你傳送數據,并且在傳送完畢時通知你。這也就是[完成]的含義。這項技術使你的程序在I/O進行過程中仍然能夠繼續處理事務。事實上,操作系統內部正是以線程來完成overlapped I/O。你可以獲得線程所有利益,而不需要付出什么痛苦的代價。

  完成端口中所謂的[端口]并不是我們在TCP/IP中所提到的端口,可以說是完全沒有關系。我到現在也沒想通一個I/O設備[I/O Device]和端口[IOCP中的Port]有什么關系。估計這個端口也迷惑了不少人。IOCP只不過是用來進行讀寫操作,和文件I/O倒是有些類似。既然是一個讀寫設備,我們所能要求它的只是在處理讀與寫上的高效。在文章的第三部分你會輕而易舉的發現IOCP設計的真正用意。


IOCP和網絡又有什么關系?

int main()
{
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    ListeningSocket = socket(AF_INET, SOCK_STREAM, 0);
   
bind(ListeningSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr));
   
listen(ListeningSocket, 5);
   
int nlistenAddrLen = sizeof(ClientAddr);
   
while(TRUE)
   
{
       
NewConnection = accept(ListeningSocket, (SOCKADDR*)&ClientAddr, &nlistenAddrLen);
       
HANDLE hThread = CreateThread(NULL, 0, ThreadFunc, (void*) NewConnection, 0, &dwTreadId);
       
CloseHandle(hThread);
   
}
   
return 0;
}


  相信只要寫過網絡的朋友,應該對這樣的結構在熟悉不過了。accept后線程被掛起,等待一個客戶發出請求,而后創建新線程來處理請求。當新線程處理客戶請求時,起初的線程循環回去等待另一個客戶請求。處理客戶請求的線程處理完畢后終結。

  在上述的并發模型中,對每個客戶請求都創建了一個線程。其優點在于等待請求的線程只需做很少的工作。大多數時間中,該線程在休眠[因為recv處于堵塞狀態]。

  但是當并發模型應用在服務器端[基于Windows NT],Windows NT小組注意到這些應用程序的性能沒有預料的那么高。特別的,處理很多同時的客戶請求意味著很多線程并發地運行在系統中。因為所有這些線程都是可運行的[沒有被掛起和等待發生什么事],Microsoft意識到NT內核花費了太多的時間來轉換運行線程的上下文[Context],線程就沒有得到很多CPU時間來做它們的工作。

  大家可能也都感覺到并行模型的瓶頸在于它為每一個客戶請求都創建了一個新線程。創建線程比起創建進程開銷要小,但也遠不是沒有開銷的。

  我們不妨設想一下:如果事先開好N個線程,讓它們在那hold[堵塞],然后可以將所有用戶的請求都投遞到一個消息隊列中去。然后那N個線程逐一從消息隊列中去取出消息并加以處理。就可以避免針對每一個用戶請求都開線程。不僅減少了線程的資源,也提高了線程的利用率。理論上很不錯,你想我等泛泛之輩都能想出來的問題,Microsoft又怎會沒有考慮到呢?!

  這個問題的解決方法就是一個稱為I/O完成端口的內核對象,他首次在Windows NT3.5中被引入。

  其實我們上面的構想應該就差不多是IOCP的設計機理。其實說穿了IOCP不就是一個消息隊列嘛!你說這和[端口]這兩字有何聯系。我的理解就是IOCP最多是應用程序和操作系統溝通的一個接口罷了。

  至于IOCP的具體設計那我也很難說得上來,畢竟我沒看過實現的代碼,但你完全可以進行模擬,只不過性能可能…,如果想深入理解IOCP, Jeffrey Ritchter的Advanced Windows 3rd其中第13章和第14張有很多寶貴的內容,你可以拿來窺視一下系統是如何完成這一切的。


實現方法

Microsoft為IOCP提供了相應的API函數,主要的就兩個,我們逐一的來看一下:
HANDLE CreateIoCompletionPort (
   
HANDLE FileHandle,              // handle to file
   
HANDLE ExistingCompletionPort,  // handle to I/O completion port
    ULONG_PTR CompletionKey,       
// completion key
   
DWORD NumberOfConcurrentThreads // number of threads to execute concurrently
);


在討論各參數之前,首先要注意該函數實際用于兩個截然不同的目的:
1.用于創建一個完成端口對象
2.將一個句柄[HANDLE]和完成端口關聯到一起

  在創建一個完成一個端口的時候,我們只需要填寫一下NumberOfConcurrentThreads這個參數就可以了。它告訴系統一個完成端口上同時允許運行的線程最大數。在默認情況下,所開線程數和CPU數量相同,但經驗給我們一個公式:
  線程數 = CPU數 * 2 + 2
要使完成端口有用,你必須把它同一個或多個設備相關聯。這也是調用CreateIoCompletionPort完成的。你要向該函數傳遞一個已有的完成端口的句柄,我們既然要處理網絡事件,那也就是將客戶的socket作為HANDLE傳進去。和一個完成鍵[對你有意義的一個32位值,也就是一個指針,操作系統并不關心你傳什么]。每當你向端口關聯一個設備時,系統向該完成端口的設備列表中加入一條信息紀錄。

另一個API就是
BOOL GetQueuedCompletionStatus(
    HANDLE CompletionPort,       
// handle to completion port
    LPDWORD lpNumberOfBytes,     
// bytes transferred
   
PULONG_PTR lpCompletionKey,   // file completion key
   
LPOVERLAPPED *lpOverlapped,   // buffer
    DWORD dwMilliseconds        
// optional timeout value
);


第一個參數指出了線程要監視哪一個完成端口。很多服務應用程序只是使用一個I/O完成端口,所有的I/O請求完成以后的通知都將發給該端口。簡單的說,GetQueuedCompletionStatus使調用線程掛起,直到指定的端口的I/O完成隊列中出現了一項或直到超時。同I/O完成端口相關聯的第3個數據結構是使線程得到完成I/O項中的信息:傳輸的字節數,完成鍵和OVERLAPPED結構的地址。該信息是通過傳遞給GetQueuedCompletionSatatus的lpdwNumberOfBytesTransferred,lpdwCompletionKey和lpOverlapped參數返回給線程的。

根據到目前為止已經講到的東西,首先來構建一個frame。下面為您說明了如何使用完成端口來開發一個echo服務器。大致如下:
  1.初始化Winsock
  2.創建一個完成端口
  3.根據服務器線程數創建一定量的線程數
  4.準備好一個socket進行bind然后listen
  5.進入循環accept等待客戶請求
  6.創建一個數據結構容納socket和其他相關信息
  7.將連進來的socket同完成端口相關聯
  8.投遞一個準備接受的請求
以后就不斷的重復5至8的過程
那好,我們用具體的代碼來展示一下細節的操作。
posted on 2007-10-09 11:59 聶文龍 閱讀(727) 評論(0)  編輯 收藏 引用 所屬分類: net work
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            日韩午夜av电影| 亚洲永久精品大片| 在线日韩欧美视频| 亚洲一区二区三区在线播放| 久久人体大胆视频| 夜夜嗨av色综合久久久综合网| 欧美一级在线亚洲天堂| 欧美午夜激情视频| 99精品视频一区二区三区| 猛男gaygay欧美视频| 亚洲一区在线免费观看| 欧美日韩在线亚洲一区蜜芽| 亚洲国产高潮在线观看| 久久久久久尹人网香蕉| 亚洲欧美日韩天堂一区二区| 欧美三级电影一区| 99国产精品久久久久老师| 欧美激情偷拍| 另类成人小视频在线| 亚洲福利国产| 亚洲电影第三页| 亚洲欧美美女| 国产欧美高清| 久久久久久噜噜噜久久久精品| 欧美一区二区三区在线| 黄色精品一区| 在线观看视频亚洲| 欧美www视频在线观看| 美腿丝袜亚洲色图| 日韩亚洲成人av在线| 亚洲毛片在线看| 国产精品v日韩精品v欧美精品网站| 欧美成人精品福利| 女女同性精品视频| 亚洲人成欧美中文字幕| 亚洲第一黄网| 欧美激情a∨在线视频播放| 亚洲精品在线观| 亚洲人精品午夜| 国产精品福利影院| 亚洲国产精品成人一区二区| 免费成人黄色片| 欧美日韩成人| 亚洲欧美日本在线| 久久国产精品久久久| 亚洲黄色在线观看| 在线视频你懂得一区| 国产一区二区三区四区hd| 免费亚洲一区| 欧美日韩亚洲高清一区二区| 亚洲欧美视频一区| 久久婷婷蜜乳一本欲蜜臀| 一区二区欧美国产| 欧美中文字幕在线播放| 日韩视频免费大全中文字幕| 一区二区三区偷拍| 亚洲大片在线观看| 一区二区日韩免费看| 韩国一区二区三区在线观看| 亚洲经典在线看| 国产欧美精品国产国产专区| 欧美国产先锋| 国产精品午夜视频| 亚洲国产合集| 国产午夜精品理论片a级大结局 | 亚洲影院色无极综合| 在线观看亚洲精品视频| 在线综合亚洲欧美在线视频| 亚洲国产高清aⅴ视频| 亚洲免费影视第一页| 亚洲精品国产品国语在线app| 亚洲淫性视频| 中文成人激情娱乐网| 美女久久一区| 久久精品欧美日韩| 国产精品麻豆成人av电影艾秋| 亚洲国产经典视频| 精久久久久久| 欧美在线你懂的| 香蕉久久夜色精品| 欧美日本不卡| 欧美激情综合色| 尤物网精品视频| 亚洲欧美日韩国产中文在线| 在线视频中文亚洲| 欧美电影在线播放| 欧美高清视频一区二区三区在线观看| 国产精品日韩专区| aⅴ色国产欧美| 99re6热在线精品视频播放速度| 久久精品国产免费看久久精品| 亚洲欧美日韩综合aⅴ视频| 欧美精品系列| 亚洲国产欧美另类丝袜| 亚洲大胆人体视频| 久久一区二区精品| 欧美福利专区| 亚洲精品国产精品国产自| 欧美国产精品一区| 免费观看30秒视频久久| 国产精品自拍一区| 亚洲视频免费| 性欧美8khd高清极品| 国产精品mm| 亚洲一区二区三区色| 亚洲欧美在线看| 国产精品久久久久久超碰| 亚洲视频观看| 欧美在线观看一二区| 国产在线拍偷自揄拍精品| 久久久国产亚洲精品| 欧美大片免费观看在线观看网站推荐| 136国产福利精品导航网址应用 | 最新亚洲视频| 欧美日韩精品免费在线观看视频| 亚洲乱码国产乱码精品精| 亚洲免费在线观看视频| 国产日韩欧美一区二区三区在线观看 | 欧美中文在线免费| 美腿丝袜亚洲色图| 亚洲免费av电影| 美女脱光内衣内裤视频久久影院 | 亚洲嫩草精品久久| 国产精品亚洲综合色区韩国| 亚洲视频观看| 久久久久国产精品人| 久久久久综合一区二区三区| 免费看的黄色欧美网站| 亚洲电影专区| 欧美性猛交xxxx乱大交退制版| 农村妇女精品| 日韩天堂在线观看| 欧美午夜无遮挡| 亚洲欧美影音先锋| 国产女人水真多18毛片18精品视频| 久久岛国电影| 免费观看成人网| 日韩一区二区精品在线观看| 久久亚洲免费| 中日韩在线视频| 久久成人免费网| 亚洲福利视频网| 欧美日韩亚洲综合| 亚洲精品国产精品国自产观看浪潮 | 欧美一级播放| 免费黄网站欧美| 国产拍揄自揄精品视频麻豆| 男女精品视频| 亚洲最新中文字幕| 亚洲欧美综合网| 亚洲欧美日韩高清| 亚洲在线播放| 亚洲五月婷婷| 国产日韩一区二区三区在线播放 | 亚洲免费在线视频一区 二区| 久久精品一本| 一区二区三区四区五区精品视频 | 亚洲性图久久| 亚洲大片在线观看| 国产午夜亚洲精品不卡| 美女任你摸久久| 亚洲在线成人| 亚洲国产一区二区三区青草影视| 久久国产欧美日韩精品| 亚洲激情视频| 国产一区欧美日韩| 欧美日韩国产综合网| 午夜精品电影| 午夜免费日韩视频| 日韩天堂av| 蜜臀av一级做a爰片久久| 一区二区三区久久网| 国产精品激情| 欧美午夜影院| 久久久国产一区二区| 一本久久综合亚洲鲁鲁五月天| 久久综合久久综合九色| 亚洲国产成人高清精品| 国产精品日韩二区| 欧美巨乳在线观看| 欧美成人免费大片| 久久国产免费看| 久久www成人_看片免费不卡| 一区二区高清视频| 亚洲狼人精品一区二区三区| 久久天天综合| 久久精品国产第一区二区三区最新章节| 亚洲永久免费精品| 99riav1国产精品视频| 亚洲第一久久影院| 韩国久久久久| 国产精品自拍小视频| 欧美日韩日日骚| 欧美成人一区二区在线| 久久久久国产成人精品亚洲午夜| 午夜欧美精品久久久久久久| 久久成人精品无人区| 午夜精品三级视频福利| 亚洲女人av| 午夜精品999|