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

隨筆 - 298  文章 - 377  trackbacks - 0
<2017年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用鏈接

留言簿(34)

隨筆分類

隨筆檔案

文章檔案

相冊

收藏夾

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

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

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

  前些日子,我們策劃做一個網(wǎng)絡(luò)游戲,我主動承擔(dān)下網(wǎng)絡(luò)這一塊,想想這還不是小case,心里偷著樂啊。網(wǎng)絡(luò)游戲好啊,網(wǎng)絡(luò)游戲?yàn)槌砂偕锨У耐婕姨峁┝藰啡ず土钊酥氐挠螒蝮w驗(yàn),他們在線上互相戰(zhàn)斗或是加入隊(duì)伍去戰(zhàn)勝共同的敵人。我信心滿滿的準(zhǔn)備開寫我的網(wǎng)絡(luò),于是乎,發(fā)現(xiàn)過去的阻塞同步模式模式根本不能拿到一個巨量多玩家[MMP]的架構(gòu)中去,直接被否定掉了。于是乎,就有了IOCP,如果能過很輕易而舉的搞掂IOCP,也就不會有這篇教程了。下面請諸位跟隨我進(jìn)入正題。


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


看來我們完全有理由相信IOCP是大型網(wǎng)絡(luò)架構(gòu)的首選。那IOCP到底是什么呢?

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

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

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


IOCP和網(wǎng)絡(luò)又有什么關(guān)系?

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;
}


  相信只要寫過網(wǎng)絡(luò)的朋友,應(yīng)該對這樣的結(jié)構(gòu)在熟悉不過了。accept后線程被掛起,等待一個客戶發(fā)出請求,而后創(chuàng)建新線程來處理請求。當(dāng)新線程處理客戶請求時,起初的線程循環(huán)回去等待另一個客戶請求。處理客戶請求的線程處理完畢后終結(jié)。

  在上述的并發(fā)模型中,對每個客戶請求都創(chuàng)建了一個線程。其優(yōu)點(diǎn)在于等待請求的線程只需做很少的工作。大多數(shù)時間中,該線程在休眠[因?yàn)閞ecv處于堵塞狀態(tài)]。

  但是當(dāng)并發(fā)模型應(yīng)用在服務(wù)器端[基于Windows NT],Windows NT小組注意到這些應(yīng)用程序的性能沒有預(yù)料的那么高。特別的,處理很多同時的客戶請求意味著很多線程并發(fā)地運(yùn)行在系統(tǒng)中。因?yàn)樗羞@些線程都是可運(yùn)行的[沒有被掛起和等待發(fā)生什么事],Microsoft意識到NT內(nèi)核花費(fèi)了太多的時間來轉(zhuǎn)換運(yùn)行線程的上下文[Context],線程就沒有得到很多CPU時間來做它們的工作。

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

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

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

  其實(shí)我們上面的構(gòu)想應(yīng)該就差不多是IOCP的設(shè)計機(jī)理。其實(shí)說穿了IOCP不就是一個消息隊(duì)列嘛!你說這和[端口]這兩字有何聯(lián)系。我的理解就是IOCP最多是應(yīng)用程序和操作系統(tǒng)溝通的一個接口罷了。

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


實(shí)現(xiàn)方法

Microsoft為IOCP提供了相應(yīng)的API函數(shù),主要的就兩個,我們逐一的來看一下:
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
);


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

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

另一個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
);


第一個參數(shù)指出了線程要監(jiān)視哪一個完成端口。很多服務(wù)應(yīng)用程序只是使用一個I/O完成端口,所有的I/O請求完成以后的通知都將發(fā)給該端口。簡單的說,GetQueuedCompletionStatus使調(diào)用線程掛起,直到指定的端口的I/O完成隊(duì)列中出現(xiàn)了一項(xiàng)或直到超時。同I/O完成端口相關(guān)聯(lián)的第3個數(shù)據(jù)結(jié)構(gòu)是使線程得到完成I/O項(xiàng)中的信息:傳輸?shù)淖止?jié)數(shù),完成鍵和OVERLAPPED結(jié)構(gòu)的地址。該信息是通過傳遞給GetQueuedCompletionSatatus的lpdwNumberOfBytesTransferred,lpdwCompletionKey和lpOverlapped參數(shù)返回給線程的。

根據(jù)到目前為止已經(jīng)講到的東西,首先來構(gòu)建一個frame。下面為您說明了如何使用完成端口來開發(fā)一個echo服務(wù)器。大致如下:
  1.初始化Winsock
  2.創(chuàng)建一個完成端口
  3.根據(jù)服務(wù)器線程數(shù)創(chuàng)建一定量的線程數(shù)
  4.準(zhǔn)備好一個socket進(jìn)行bind然后listen
  5.進(jìn)入循環(huán)accept等待客戶請求
  6.創(chuàng)建一個數(shù)據(jù)結(jié)構(gòu)容納socket和其他相關(guān)信息
  7.將連進(jìn)來的socket同完成端口相關(guān)聯(lián)
  8.投遞一個準(zhǔn)備接受的請求
以后就不斷的重復(fù)5至8的過程
那好,我們用具體的代碼來展示一下細(xì)節(jié)的操作。
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>
            国产亚洲一二三区| 国产精品扒开腿做爽爽爽视频| 亚洲黄网站黄| 欧美综合二区| 欧美国产在线视频| 99ri日韩精品视频| 在线看日韩av| 国产夜色精品一区二区av| 久久亚洲春色中文字幕| 亚洲图片在线| 一区二区国产在线观看| 欧美高清视频在线| 欧美一区二区在线播放| 91久久久亚洲精品| 国产精品一二三四区| 久久国产99| 亚洲一二三区在线观看| 亚洲人成在线播放| 亚洲少妇最新在线视频| 亚洲激情在线观看视频免费| 亚洲高清影视| 日韩写真在线| 欧美伊人久久大香线蕉综合69| 亚洲九九九在线观看| 国产手机视频一区二区| 国语精品一区| 日韩亚洲欧美在线观看| 一区二区三区回区在观看免费视频| 亚洲神马久久| 久久免费黄色| 日韩一区二区精品葵司在线| 欧美亚洲一区二区在线| 欧美激情亚洲| 伊人成年综合电影网| 亚洲电影自拍| 亚洲高清视频一区二区| 一区二区精品在线| 久久综合色播五月| 亚洲午夜av电影| 欧美日韩精品一区| 亚洲三级影片| 亚洲国产天堂久久国产91| 欧美一区午夜精品| 国产精品亚洲综合色区韩国| 亚洲校园激情| 亚洲欧美日韩一区二区在线 | 日韩亚洲欧美一区| 六月婷婷久久| 欧美在线视频免费| 国产精品久久久久婷婷| 亚洲调教视频在线观看| 日韩午夜在线视频| 国产精品激情av在线播放| 亚洲国产成人av| 久久久蜜桃精品| 校园春色综合网| 欧美精品激情blacked18| 狠狠色狠狠色综合日日小说| 午夜欧美理论片| 欧美一区二区三区男人的天堂| 欧美视频在线不卡| 亚洲人成在线观看网站高清| 亚洲欧洲一区| 国产日产欧美一区| 欧美一级黄色录像| 欧美中文字幕在线播放| 国产亚洲欧美激情| 亚洲欧美日韩国产综合精品二区| 欧美一区二区三区四区高清| 午夜天堂精品久久久久| 宅男精品视频| 亚洲精品国精品久久99热| 亚洲欧美一区在线| 亚洲国产专区校园欧美| 91久久久久久国产精品| 老司机午夜精品视频在线观看| 亚洲激情校园春色| 99日韩精品| 亚洲裸体视频| 欧美成人精品一区二区三区| 蜜臀久久久99精品久久久久久| 亚洲一区二区影院| 欧美日韩在线三区| 一区二区三区四区蜜桃| 亚洲伦理自拍| 欧美日韩一区在线观看视频| 99re热这里只有精品免费视频| 99视频在线观看一区三区| 91久久夜色精品国产网站| 久久久久高清| 欧美激情中文字幕一区二区| 黑人巨大精品欧美一区二区| 性久久久久久久| 亚洲欧美日韩中文在线制服| 欧美日韩在线免费视频| 91久久精品一区二区三区| 欲香欲色天天天综合和网| 久久国产婷婷国产香蕉| 久久久精品tv| 亚洲日本免费| 国产欧美一区二区白浆黑人| 久久国产精品第一页| 欧美一二三视频| 激情懂色av一区av二区av| 欧美福利专区| 午夜在线不卡| 亚洲久久成人| 蜜桃久久av一区| 香蕉久久夜色精品国产| 国产一区91精品张津瑜| 最新日韩av| 美女视频黄a大片欧美| 日韩午夜免费视频| 在线不卡a资源高清| 欧美电影资源| 久久综合给合久久狠狠狠97色69| 性欧美xxxx视频在线观看| 一区二区欧美日韩| 国产综合自拍| 欧美三级视频在线播放| 欧美国产日韩视频| 免费在线日韩av| 欧美精品免费观看二区| 欧美大片免费观看| 欧美电影免费观看高清完整版| 久久综合九色九九| 欧美韩日精品| 欧美日韩国产首页在线观看| 欧美激情中文字幕乱码免费| 欧美国产第一页| 欧美片在线观看| 国产精品黄页免费高清在线观看| 欧美性大战久久久久久久| 国产精品家庭影院| 黄色精品免费| 一区二区三区 在线观看视频| 亚洲先锋成人| 蜜臀av国产精品久久久久| 亚洲激情在线观看视频免费| 99www免费人成精品| 亚洲女人天堂成人av在线| 久久精品国产第一区二区三区最新章节 | 久久久亚洲精品一区二区三区 | 久久中文字幕一区| 久久精品二区| 亚洲人午夜精品| 欧美一区二区成人| 一级成人国产| 亚洲少妇中出一区| 亚洲二区在线视频| 亚洲一区影院| 欧美男人的天堂| 亚洲第一在线视频| 欧美在线黄色| 亚洲综合导航| 欧美色播在线播放| 亚洲精品国产精品国自产观看 | 欧美福利电影网| 伊人成人网在线看| 老司机久久99久久精品播放免费| 制服丝袜亚洲播放| 欧美日韩精品一区二区三区| 亚洲国产日韩欧美在线99| 久久综合婷婷| 欧美成人乱码一区二区三区| 在线日韩av| 亚洲精品日韩在线观看| 欧美伦理在线观看| 亚洲欧美日韩精品在线| 亚洲欧美日韩电影| 激情婷婷久久| 亚洲品质自拍| 国产亚洲欧美一级| 欧美成人一区二免费视频软件| 欧美成人国产一区二区| 午夜精品短视频| 久久影院亚洲| 亚洲四色影视在线观看| 亚洲男女自偷自拍| 亚洲级视频在线观看免费1级| 亚洲精品综合久久中文字幕| 国产精品美女一区二区| 男男成人高潮片免费网站| 欧美理论电影在线播放| 久久这里有精品15一区二区三区| 欧美成人免费在线视频| 久久精品亚洲一区| 欧美色播在线播放| 亚洲国产天堂久久综合| 激情成人中文字幕| 亚洲男人的天堂在线aⅴ视频| 午夜精品在线观看| 欧美日韩国产一区二区三区| 伊人久久大香线蕉综合热线 | 欧美国产精品v| 国产精品www| 亚洲性xxxx| 欧美一级久久久| 国模大胆一区二区三区| 亚洲欧美在线观看|