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

sherrylso

C++博客 首頁(yè) 新隨筆 聯(lián)系 聚合 管理
  18 Posts :: 0 Stories :: 124 Comments :: 0 Trackbacks

         本文主要探討一下windows平臺(tái)上的完成端口開(kāi)發(fā)及其與之相關(guān)的幾個(gè)重要的技術(shù)概念,這些概念都是與基于IOCP的開(kāi)發(fā)密切相關(guān)的,對(duì)開(kāi)發(fā)人員來(lái)講,又不得不給予足夠重視的幾個(gè)概念:
1) 基于IOCP實(shí)現(xiàn)的服務(wù)吞吐量
2)IOCP模式下的線程切換
3)基于IOCP實(shí)現(xiàn)的消息的亂序問(wèn)題。

一、IOCP簡(jiǎn)介
    提到IOCP,大家都非常熟悉,其基本的編程模式,我就不在這里展開(kāi)了。在這里我主要是把IOCP中所提及的概念做一個(gè)基本性的總結(jié)。IOCP的基本架構(gòu)圖如下:
 

如圖所示:在IOCP中,主要有以下的參與者:
--》完成端口:是一個(gè)FIFO隊(duì)列,操作系統(tǒng)的IO子系統(tǒng)在IO操作完成后,會(huì)把相應(yīng)的IO packet放入該隊(duì)列。
--》等待者線程隊(duì)列:通過(guò)調(diào)用GetQueuedCompletionStatus API,在完成端口上等待取下一個(gè)IO packet。
--》執(zhí)行者線程組:已經(jīng)從完成端口上獲得IO packet,在占用CPU進(jìn)行處理。
除了以上三種類型的參與者。我們還應(yīng)該注意兩個(gè)關(guān)聯(lián)關(guān)系,即:
--》IO Handle與完成端口相關(guān)聯(lián):任何期望使用IOCP的方式來(lái)處理IO請(qǐng)求的,必須將相應(yīng)的IO Handle與該完成端口相關(guān)聯(lián)。需要指出的時(shí),這里的IO Handle,可以是File的Handle,或者是Socket的Handle。
--》線程與完成端口相關(guān)聯(lián):任何調(diào)用GetQueuedCompletionStatus API的線程,都將與該完成端口相關(guān)聯(lián)。在任何給定的時(shí)候,該線程只能與一個(gè)完成端口相關(guān)聯(lián),與最后一次調(diào)用的GetQueuedCompletionStatus為準(zhǔn)。
二、高并發(fā)的服務(wù)器(基于socket)實(shí)現(xiàn)方法
        一般來(lái)講,實(shí)現(xiàn)基于socket的服務(wù)器,有三種實(shí)現(xiàn)的方式(thread per request的方式,我就不提了:)):
第一、線程池的方式。使用線程池來(lái)對(duì)客戶端請(qǐng)求進(jìn)行服務(wù)。使用這種方式時(shí),當(dāng)客戶端對(duì)服務(wù)器的連接是短連接(所謂的短連接,即:客戶端對(duì)服務(wù)器不是長(zhǎng)時(shí)間連接)時(shí),是可以考慮的。但是,如若客戶端對(duì)服務(wù)器的連接是長(zhǎng)連接時(shí),我們需要限制服務(wù)器端的最大連接數(shù)目為線程池線程的最大數(shù)目,而這應(yīng)用的設(shè)計(jì)本身來(lái)講,是不好的設(shè)計(jì)方式,scalability會(huì)存在問(wèn)題。
第二、基于Select的服務(wù)器實(shí)現(xiàn)。其本質(zhì)是,使用Select(操作系統(tǒng)提供的API)來(lái)監(jiān)視連接是否可讀,可寫,或者是否出錯(cuò)。相比于前一種方式,Select允許應(yīng)用使用一個(gè)線程(或者是有限幾個(gè)線程)來(lái)監(jiān)視連接的可讀寫性。當(dāng)有連接可讀可寫時(shí),應(yīng)用可以以non-bolock的方式讀寫socket上的數(shù)據(jù)。使用Select的方式的缺點(diǎn)是,當(dāng)Select所監(jiān)視的連接數(shù)目在千的數(shù)量級(jí)時(shí),性能會(huì)打折扣。這是因?yàn)椴僮飨到y(tǒng)內(nèi)核需要在內(nèi)部對(duì)這些Socket進(jìn)行輪詢,以檢查其可讀寫性。另一個(gè)問(wèn)題是:應(yīng)用必須在處理完所有的可讀寫socket的IO請(qǐng)求之后,才能再次調(diào)用Select,進(jìn)行下一輪的檢查,否則會(huì)有潛在的問(wèn)題。這樣,造成的結(jié)果是,對(duì)一些請(qǐng)求的處理會(huì)出現(xiàn)饑餓的現(xiàn)象。
        一般common的做法是Select結(jié)合Leader-Follower設(shè)計(jì)模式使用。不過(guò)不管怎樣,Select的本質(zhì)造成了其在Scalability的問(wèn)題是不如IOCP,這也是很多high-scalabe的服務(wù)器采用IOCP的原因。
第三、IOCP實(shí)現(xiàn)高并發(fā)的服務(wù)器。IOCP是實(shí)現(xiàn)high-scalabe的服務(wù)器的首選。其特點(diǎn)我們專門在下一小姐陳述。
三、IOCP開(kāi)發(fā)的幾個(gè)概念
第一、服務(wù)器的吞吐量問(wèn)題。
      我們都知道,基于IOCP的開(kāi)發(fā)是異步IO的,也正是這一技術(shù)的本質(zhì),決定了IOCP所實(shí)現(xiàn)的服務(wù)器的高吞吐量。
       我們舉一個(gè)及其簡(jiǎn)化的例子,來(lái)說(shuō)明這一問(wèn)題。在網(wǎng)絡(luò)服務(wù)器的開(kāi)發(fā)過(guò)程中,影響其性能吞吐量的,有很多因素,在這里,我們只是把關(guān)注點(diǎn)放在兩個(gè)方面,即:網(wǎng)絡(luò)IO速度與Disk IO速度。我們假設(shè):在一個(gè)千兆的網(wǎng)絡(luò)環(huán)境下,我們的網(wǎng)絡(luò)傳輸速度的極限是大概125M/s,而Disk IO的速度是10M/s。在這樣的前提下,慢速的Disk 設(shè)備會(huì)成為我們整個(gè)應(yīng)用的瓶頸。我們假設(shè)線程A負(fù)責(zé)從網(wǎng)絡(luò)上讀取數(shù)據(jù),然后將這些數(shù)據(jù)寫入Disk。如果對(duì)Disk的寫入是同步的,那么線程A在等待寫完Disk的過(guò)程是不能再?gòu)木W(wǎng)絡(luò)上接受數(shù)據(jù)的,在寫入Disk的時(shí)間內(nèi),我們可以認(rèn)為這時(shí)候Server的吞吐量為0(沒(méi)有接受新的客戶端請(qǐng)求)。對(duì)于這樣的同步讀寫Disk,一些的解決方案是通過(guò)增加線程數(shù)來(lái)增加服務(wù)器處理的吞吐量,即:當(dāng)線程A從網(wǎng)絡(luò)上接受數(shù)據(jù)后,驅(qū)動(dòng)另外單獨(dú)的線程來(lái)完成讀寫Disk任務(wù)。這樣的方案缺點(diǎn)是:需要線程間的合作,需要線程間的切換(這是另一個(gè)我們要討論的問(wèn)題)。而IOCP的異步IO本質(zhì),就是通過(guò)操作系統(tǒng)內(nèi)核的支持,允許線程A以非阻塞的方式向IO子系統(tǒng)投遞IO請(qǐng)求,而后馬上從網(wǎng)絡(luò)上讀取下一個(gè)客戶端請(qǐng)求。這樣,結(jié)果是:在不增加線程數(shù)的情況下,IOCP大大增加了服務(wù)器的吞吐量。說(shuō)到這里,聽(tīng)起來(lái)感覺(jué)很像是DMA。的確,許多軟件的實(shí)現(xiàn)技術(shù),在本質(zhì)上,與硬件的實(shí)現(xiàn)技術(shù)是相通的。另外一個(gè)典型的例子是硬件的流水線技術(shù),同樣,在軟件領(lǐng)域,也有很著名的應(yīng)用。好像話題扯遠(yuǎn)了,呵呵:)
第二、線程間的切換問(wèn)題。
         服務(wù)器的實(shí)現(xiàn),通過(guò)引入IOCP,會(huì)大大減少Thread切換帶來(lái)的額外開(kāi)銷。我們都知道,對(duì)于服務(wù)器性能的一個(gè)重要的評(píng)估指標(biāo)就是:System\Context Switches,即單位時(shí)間內(nèi)線程的切換次數(shù)。如果在每秒內(nèi),線程的切換次數(shù)在千的數(shù)量級(jí)上,這就意味著你的服務(wù)器性能值得商榷。Context Switches/s應(yīng)該越小越好。說(shuō)到這里,我們來(lái)重新審視一下IOCP。
     完成端口的線程并發(fā)量可以在創(chuàng)建該完成端口時(shí)指定(即NumberOfConcurrentThreads參數(shù))。該并發(fā)量限制了與該完成端口相關(guān)聯(lián)的可運(yùn)行線程的數(shù)目(就是前面我在IOCP簡(jiǎn)介中提到的執(zhí)行者線程組的最大數(shù)目)。當(dāng)與該完成端口相關(guān)聯(lián)的可運(yùn)行線程的總數(shù)目達(dá)到了該并發(fā)量,系統(tǒng)就會(huì)阻塞任何與該完成端口相關(guān)聯(lián)的后續(xù)線程的執(zhí)行,直到與該完成端口相關(guān)聯(lián)的可運(yùn)行線程數(shù)目下降到小于該并發(fā)量為止。最有效的假想是發(fā)生在有完成包在隊(duì)列中等待,而沒(méi)有等待被滿足,因?yàn)榇藭r(shí)完成端口達(dá)到了其并發(fā)量的極限。此時(shí),一個(gè)正在運(yùn)行中的線程調(diào)用GetQueuedCompletionStatus時(shí),它就會(huì)立刻從隊(duì)列中取走該完成包。這樣就不存在著環(huán)境的切換,因?yàn)樵撎幱谶\(yùn)行中的線程就會(huì)連續(xù)不斷地從隊(duì)列中取走完成包,而其他的線程就不能運(yùn)行了。
     完成端口的線程并發(fā)量的建議值就是你系統(tǒng)CPU的數(shù)目。在這里,要區(qū)分清楚的是,完成端口的線程并發(fā)量與你為完成端口創(chuàng)建的工作者線程數(shù)是沒(méi)有任何關(guān)系的,工作者線程數(shù)的數(shù)目,完全取決于你的整個(gè)應(yīng)用的設(shè)計(jì)(當(dāng)然這個(gè)不宜過(guò)大,否則失去了IOCP的本意:))。
第三、IOCP開(kāi)發(fā)過(guò)程中的消息亂序問(wèn)題。
     使用IOCP開(kāi)發(fā)的問(wèn)題在于它的復(fù)雜。我們都知道,在使用TCP時(shí),TCP協(xié)議本身保證了消息傳遞的次序性,這大大降低了上層應(yīng)用的復(fù)雜性。但是當(dāng)使用IOCP時(shí),問(wèn)題就不再那么簡(jiǎn)單。如下例:
  
       三個(gè)線程同時(shí)從IOCP中讀取Msg1, Msg2,與Msg3。由于TCP本身消息傳遞的有序性,所以,在IOCP隊(duì)列內(nèi),Msg1-Msg2-Msg3保證了有序性。三個(gè)線程分別從IOCP中取出Msg1,Msg2與Msg3,然后三個(gè)線程都會(huì)將各自取到的消息投遞到邏輯層處理。在邏輯處理層的實(shí)現(xiàn),我們不應(yīng)該假定Msg1-Msg2-Msg3順序,原因其實(shí)很簡(jiǎn)單,在Time 1~Time 2的時(shí)間段內(nèi),三個(gè)線程被操作系統(tǒng)調(diào)度的先后次序是不確定的,所以在到達(dá)邏輯處理層,
Msg1,Msg2與Msg3的次序也就是不確定的。所以,邏輯處理層的實(shí)現(xiàn),必須考慮消息亂序的情況,必須考慮多線程環(huán)境下的程序?qū)崿F(xiàn)。
        在這里,我把消息亂序的問(wèn)題單列了出來(lái)。其實(shí)在IOCP的開(kāi)發(fā)過(guò)程中,相比于同步的方式,應(yīng)該還有其它更多的難題需要解決,這也是與Select方式相比,IOCP的缺點(diǎn),實(shí)現(xiàn)復(fù)雜度高。
結(jié)束語(yǔ):
    ACE的Proactor Framework, 對(duì)windows平臺(tái)的IOCP做了基于Proactor設(shè)計(jì)模式的,面向?qū)ο蟮姆庋b,這在一定程度上簡(jiǎn)化了應(yīng)用開(kāi)發(fā)的難度,是一個(gè)很好的異步IO的開(kāi)發(fā)框架,推薦學(xué)習(xí)使用。 
Reference:
    Microsoft Technet,Inside I/O Completion Ports

posted on 2007-08-26 16:06 愛(ài)上龍卷風(fēng) 閱讀(16545) 評(píng)論(23)  編輯 收藏 引用

Feedback

# re: 完成端口(IOCP)編程探討[未登錄](méi) 2007-09-05 07:15 小明
對(duì)于你提出的第三個(gè)問(wèn)題,亂序問(wèn)題

一般寫IOCP程序,都會(huì)讓每個(gè)socket和一個(gè)buffer關(guān)聯(lián)
只要讓W(xué)SARecv保證每次按次序的寫到buffer
然后邏輯層也按照次序的來(lái)讀取信息(需要有鎖來(lái)控制)
這樣就不會(huì)有亂序問(wèn)題了。

不知道你對(duì)于這個(gè)問(wèn)題有什么高招?  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-09-06 10:11 NULL
回答下上面的問(wèn)題,你的問(wèn)題就有問(wèn)題,如果只有一個(gè)recv投遞,那就不會(huì)存在亂序的問(wèn)題,如果你投遞n個(gè),按順序1.2.3,但是你怎么保證recv不是按照2.3.1返回的呢?  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-10-20 15:30 RedFox
我也是進(jìn)來(lái)討論你提出的第三個(gè)問(wèn)題的。

通常的做法是一個(gè) Socket 用一個(gè) WSARecv 異步操作,有完成事件時(shí),先處理完這個(gè)異步操作時(shí),才再次發(fā)出下一個(gè) WSARecv 異步操作。這樣就不會(huì)有你說(shuō)的消息亂序問(wèn)題了。

而你說(shuō)的一次對(duì)同一個(gè) socket 提交 n 個(gè) WSARecv 操作。我認(rèn)為是不可取的。
  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-10-21 20:15 愛(ài)上龍卷風(fēng)
@RedFox
你應(yīng)該弄錯(cuò)了,的確,如果按照你的說(shuō)法,就是單線程了,沒(méi)有多線程。
當(dāng)然沒(méi)有問(wèn)題。但是,你的performance是沒(méi)法保證的,幾乎沒(méi)有什么
throughput的。
  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-10-21 20:17 愛(ài)上龍卷風(fēng)
@小明
對(duì)于你的問(wèn)題,我同意NULL的解釋  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-10-22 08:41 RedFox
可能是我水平不夠。
的確,我是對(duì)每個(gè) socket 做一個(gè) WSARecv. 處理完這個(gè) WSARecv 後我再發(fā)起下一個(gè) WSARecv. 如果有 1000個(gè)連接,而 IOCP 裡就有 1000個(gè) IO請(qǐng)求包。

而你說(shuō)的一個(gè) socket 就發(fā)起 N 個(gè) WSARecv. 首先,讀到的數(shù)據(jù)次序不能保證,再次,如果 socket 關(guān)閉時(shí),你也會(huì)收到 N 個(gè)關(guān)閉消息,你應(yīng)該在哪個(gè)關(guān)閉消息時(shí)去釋放資源呢?  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2007-11-11 14:19 愛(ài)上龍卷風(fēng)
@RedFox
你說(shuō)的收到N 個(gè)關(guān)閉消息,指的是你自己定義的嗎?
不管怎么樣,引用計(jì)數(shù)技術(shù)應(yīng)該能幫到你。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-01-07 17:12 唐新發(fā)
錯(cuò)別字:小組不是小姐
第三、IOCP實(shí)現(xiàn)高并發(fā)的服務(wù)器。IOCP是實(shí)現(xiàn)high-scalabe的服務(wù)器的首選。其特點(diǎn)我們專門在下一小姐陳述。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-01-07 23:08 abettor.org
@RedFox
我贊同你的看法。
但是,是否有更高效的辦法呢?
我覺(jué)得如果業(yè)務(wù)邏輯層速度很慢的化,可以把按上述方法WSARecv到的數(shù)據(jù)再放到一個(gè)池里緩沖一下。不知道會(huì)不會(huì)適得其反。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-01-11 22:09 愛(ài)上龍卷風(fēng)
@abettor.org
應(yīng)該不是業(yè)務(wù)邏輯層速度很慢的問(wèn)題,cpu的指令執(zhí)行都是很快的,除非你訪問(wèn)慢速的IO設(shè)備。
對(duì)于業(yè)務(wù)邏輯層,應(yīng)該提高的是并發(fā)的吞吐量。

  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-03-31 09:05 RedFox
@abettor.org

IOCP 只處理封包,收到一個(gè)完整的包後,就POST到工作線程池,由工作線程池進(jìn)行分配線程處理  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-05-24 23:46 iunknown
@愛(ài)上龍卷風(fēng)
你應(yīng)該弄錯(cuò)了,的確,如果按照你的說(shuō)法,就是單線程了,沒(méi)有多線程。
當(dāng)然沒(méi)有問(wèn)題。但是,你的performance是沒(méi)法保證的,幾乎沒(méi)有什么
throughput的。


關(guān)于這一點(diǎn),有實(shí)現(xiàn)過(guò)一個(gè)用單線程負(fù)責(zé) IO 操作,線程池負(fù)責(zé)業(yè)務(wù)邏輯處理的 server framework 。負(fù)責(zé) IO 的單線程,主要是執(zhí)行 WSARecv, WSASend ,GetQueuedCompletionPort,具體的業(yè)務(wù)邏輯不在這個(gè)線程里面執(zhí)行。
用這個(gè)框架實(shí)現(xiàn)過(guò)一個(gè) echo server ,進(jìn)行大壓力測(cè)試,發(fā)現(xiàn) throughput 還是很高的。可以認(rèn)為在目前的 CPU 速度下,只是執(zhí)行 WSARecv,WSASend,GetQueuedCompletionPort ,還是足夠快的。
如果在同一臺(tái)機(jī)運(yùn)行 client 和 server,測(cè)試的結(jié)果是可以達(dá)到每秒 send 10萬(wàn), recv 10萬(wàn)。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-05-24 23:49 iunknown
@RedFox
我也是進(jìn)來(lái)討論你提出的第三個(gè)問(wèn)題的。

通常的做法是一個(gè) Socket 用一個(gè) WSARecv 異步操作,有完成事件時(shí),先處理完這個(gè)異步操作時(shí),才再次發(fā)出下一個(gè) WSARecv 異步操作。這樣就不會(huì)有你說(shuō)的消息亂序問(wèn)題了。

而你說(shuō)的一次對(duì)同一個(gè) socket 提交 n 個(gè) WSARecv 操作。我認(rèn)為是不可取的。


也是用這個(gè)方法來(lái)實(shí)現(xiàn)的,這樣做會(huì)比較簡(jiǎn)單,可以避免消息的亂序問(wèn)題。而且在關(guān)閉 socket 釋放資源的時(shí)候,也相對(duì)容易控制。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-05-29 16:56 愛(ài)上龍卷風(fēng)
@iunknown
關(guān)于你提到的框架,本質(zhì)上是多線線程的。負(fù)責(zé) IO 的線程數(shù)目理論上本來(lái)就應(yīng)該是你機(jī)器cpu的個(gè)數(shù)。前提是你保證你的io設(shè)計(jì)是異步執(zhí)行的。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-06-09 17:14 iunknown
@愛(ài)上龍卷風(fēng)
>>>關(guān)于你提到的框架,本質(zhì)上是多線線程的。負(fù)責(zé) IO 的線程數(shù)目理論上本來(lái)就應(yīng)該是你機(jī)器cpu的個(gè)數(shù)。前提是你保證你的io設(shè)計(jì)是異步執(zhí)行的。

框架中用到了多線程,不過(guò)用于處理 IOCP 的線程(或者稱為用于處理前端網(wǎng)絡(luò) IO 的線程)就只有一個(gè)。后端的線程池是用于處理具體的業(yè)務(wù)的,不會(huì)涉及前端的網(wǎng)絡(luò) IO 的。前端的網(wǎng)絡(luò) IO 可以非常清晰地剝離出來(lái),由一個(gè)單獨(dú)的線程來(lái)負(fù)責(zé)。在 input 的時(shí)候,在前端的 IO 線程中讀入數(shù)據(jù),放入 inputqueue,線程池負(fù)責(zé) inputqueue;output 的時(shí)候,線程池把結(jié)果放入 outputqueue ,前端 IO 線程負(fù)責(zé)處理 outputqueue 。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-06-09 17:19 iunknown
這里有一個(gè)用 zero byte buffer 策略集成 iocp 到 libevent 的方案。
具體的源代碼:http://spserver.googlecode.com/files/libevent-1.4.4-iocp-3.zip

vc6 的 dsw 文件在 libevent-1.4.4-iocp-3/libevent-iocp 目錄中。
這個(gè)方案就是單線程負(fù)責(zé) IO ,里面有 echo_iocp.exe 和 testiocpstress.exe ,可以試試看它的性能。

方案的描述可以看看
http://monkeymail.org/archives/libevent-users/2008-June/001269.html  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-06-23 23:41 飯中淹
多個(gè)recv可以在overlapped上進(jìn)行順序綁定
recv請(qǐng)求的順序,決定了它收到的數(shù)據(jù)的先后順序。
只要進(jìn)行簡(jiǎn)單的排序,就可以保證recv的數(shù)據(jù)的順序正確。

如果用多個(gè)recv的話,可以直接去掉recvbuf了。對(duì)于一個(gè)socket,去掉recvbuf相當(dāng)于是減少了內(nèi)存復(fù)制,因?yàn)镮o層會(huì)把WSARecv進(jìn)去的buf拿來(lái)直接作為緩沖來(lái)保存收到的數(shù)據(jù)。

如果不去掉recvbuf,那么多recv就看起來(lái)不是那么有意義了。



另外,iocp的程序可以寫的比較Open一點(diǎn),不要老想著節(jié)省內(nèi)存。對(duì)于buffer和overlapped結(jié)構(gòu),可以分別用一個(gè)池來(lái)管理,而不是固定寫死。這樣不需要等待處理完一次受到的buffer,就能緊接著發(fā)出下一次recv,而且在這個(gè)過(guò)程中overlapped這個(gè)結(jié)構(gòu)還能夠重用,效率自然就會(huì)提升的。




  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2008-10-23 17:15 r2100
@NULL
回答下上面的問(wèn)題,你的問(wèn)題就有問(wèn)題,如果只有一個(gè)recv投遞,那就不會(huì)存在亂序的問(wèn)題,如果你投遞n個(gè),按順序1.2.3,但是你怎么保證recv不是按照2.3.1返回的呢?
分別給1.2.3的overlapped做上記號(hào)1.2.3,返回時(shí)加個(gè)排序就可以了。

  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2009-10-19 17:42 @jurver
我同意@RedFox的觀點(diǎn)。
1.給一個(gè)socket投遞多個(gè)Recv,只有在數(shù)據(jù)需要復(fù)制到自己的緩沖區(qū)(有可能有多個(gè)緩沖區(qū))的情況。多數(shù)情況下并不需要。對(duì)一個(gè)socket投遞多個(gè)recv請(qǐng)求。由于接收到的數(shù)據(jù)也是按發(fā)送的順序,而完成端口是按隊(duì)列來(lái)處理的。所以接收的數(shù)據(jù)是按投遞的接收請(qǐng)求復(fù)制到自己的緩沖區(qū)。舉例:你的本意是接受1.“hello”;2."MM";3."GG".而假設(shè)發(fā)送的順序是3;2;1;,那么第一個(gè)recv原本希望得到1 "hello",可是現(xiàn)在得到了 3“GG”。就會(huì)和你本意相差甚遠(yuǎn),所以多個(gè)Recv投遞是不理想的。根本不可取。還不如接收到數(shù)據(jù),復(fù)制出來(lái)。再接收。  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討[未登錄](méi) 2010-01-29 18:06 wang
樓主的設(shè)計(jì) 優(yōu)點(diǎn)是可以增大吞吐量
擁有多個(gè)掛起的讀操作增加了服務(wù)器的吞吐量,這是因?yàn)門CP/IP包將會(huì)被直接寫到我們傳入的buffer而不是TCP/IP棧(不會(huì)有雙緩沖)。

其它同學(xué)的設(shè)計(jì)也有優(yōu)點(diǎn),采用什么樣的設(shè)計(jì) 取決于你的業(yè)務(wù),

但如何 避免亂序呢? 我想到一個(gè)辦法 每個(gè)掛起的讀 都有一個(gè)序列號(hào),讀成功后按照這些序列號(hào) 再排序 組合包 。

歡迎探討 wanglovec@163.com QQ: 50713022  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2011-04-06 17:37 Geph0rce
@唐新發(fā)
小節(jié)  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討[未登錄](méi) 2012-07-04 16:10 1
good  回復(fù)  更多評(píng)論
  

# re: 完成端口(IOCP)編程探討 2012-12-25 14:06 ILOLI
@@jurver
你這樣收到數(shù)據(jù)亂序是發(fā)送端的問(wèn)題,和接收端沒(méi)有半毛錢的關(guān)系。  回復(fù)  更多評(píng)論
  


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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一区精品变态类天堂| 国产一区二区三区久久久久久久久 | 久久久久国产精品一区二区| 久久爱91午夜羞羞| 亚洲一区成人| 欧美在线一级视频| 欧美~级网站不卡| 欧美国产日产韩国视频| 亚洲激情在线播放| 亚洲精品国产精品乱码不99按摩| 亚洲免费播放| 亚洲欧美在线aaa| 六月婷婷久久| 国产精品久久久久国产精品日日| 国内精品视频久久| 日韩视频在线观看国产| 亚洲免费影视| 久久精品动漫| 亚洲精品一区二区三区在线观看| 亚洲欧美在线一区| 美女精品视频一区| 国产精品日韩在线播放| 亚洲黄一区二区| 性色一区二区| 亚洲日本国产| 久久综合激情| 国产精品专区一| 日韩一级精品| 蜜桃久久精品乱码一区二区| 一本色道精品久久一区二区三区| 久久精品五月婷婷| 国产精品二区在线观看| 91久久国产自产拍夜夜嗨| 欧美一级日韩一级| 亚洲精品之草原avav久久| 久久久久**毛片大全| 国产精品美女久久久久aⅴ国产馆| 亚洲国产欧美一区二区三区同亚洲| 亚洲专区在线| 久久久久久9| 99热免费精品在线观看| 久热精品在线| 国产亚洲va综合人人澡精品| 一本色道久久88精品综合| 欧美成人一区二区三区| 性欧美xxxx视频在线观看| 国产精品萝li| 亚洲一区二三| 99精品99久久久久久宅男| 欧美激情一区二区三区成人| 1000部精品久久久久久久久| 久久久久久亚洲精品不卡4k岛国| 一区二区三区免费观看| 欧美日韩精品免费| 一本久久综合亚洲鲁鲁| 亚洲欧洲日韩在线| 欧美日韩久久久久久| 亚洲精品一区二区三区在线观看| 免费黄网站欧美| 久久国产免费| 在线看日韩av| 欧美成人午夜激情视频| 另类成人小视频在线| 亚洲国产日韩一区| 欧美激情亚洲另类| 欧美精品播放| 亚洲一区免费网站| 亚洲欧美日韩在线观看a三区| 国产精品视频一二三| 欧美在线亚洲在线| 久久精品视频免费观看| 亚洲国产精品久久久久婷婷老年 | 国产欧美丝祙| 久久久亚洲国产天美传媒修理工| 久久国产精品电影| 亚洲国产精品专区久久| 亚洲人成久久| 国产精品扒开腿做爽爽爽软件 | 亚洲精品日韩在线观看| 欧美视频中文字幕| 久久久国产91| 欧美电影免费观看网站| 亚洲五月六月| 欧美在线国产| 99热精品在线| 午夜精品在线视频| 91久久亚洲| 亚洲女人天堂av| 亚洲精品视频在线播放| 亚洲特级片在线| 亚洲国产高清高潮精品美女| 亚洲毛片一区| 一区二区三区亚洲| 一区二区三区视频在线播放| 一区二区三区在线免费播放| 一区二区黄色| 欧美黄免费看| 亚洲高清资源| 国产精品久久久久久久久久ktv| 久久精品国产2020观看福利| 免费一区二区三区| 欧美专区福利在线| 欧美国产亚洲精品久久久8v| 欧美专区中文字幕| 欧美日韩国产美| 欧美不卡一区| 国产视频一区二区在线观看| 亚洲精品一区二区三区福利| 影音先锋中文字幕一区| 亚洲女爱视频在线| 亚洲一区二区av电影| 免费不卡在线视频| 久久九九国产精品怡红院| 欧美色一级片| 亚洲精品乱码久久久久久蜜桃91 | 国产一区二区三区黄| 99成人免费视频| 亚洲美女av网站| 久久综合九九| 美女久久一区| 好男人免费精品视频| 亚洲欧美日韩精品一区二区| 亚洲一区欧美激情| 欧美日韩一区二区视频在线| 亚洲欧洲另类国产综合| 亚洲欧洲精品一区二区精品久久久 | 亚洲国产精选| 久久精品视频在线| 久久久久综合一区二区三区| 国产日韩欧美一区二区三区四区 | 欧美精品99| 91久久在线观看| 亚洲精品一二三| 欧美精品一区二区精品网| 亚洲高清二区| 亚洲精品一区二区三区婷婷月 | 亚洲黄色有码视频| 亚洲精品国精品久久99热| 免费久久99精品国产自| 亚洲第一成人在线| 99国产精品国产精品久久| 欧美精品1区2区| 在线视频你懂得一区| 销魂美女一区二区三区视频在线| 国产精品久久久久久久久久ktv| 亚洲综合日本| 免费观看国产成人| 日韩系列在线| 国产精品国产三级国产普通话蜜臀 | 久久五月天婷婷| 亚洲第一在线综合在线| 9国产精品视频| 国产精品每日更新在线播放网址| 欧美成人嫩草网站| 亚洲日本激情| 亚洲影院免费观看| 国产欧美一区二区精品仙草咪| 欧美一区视频| 欧美成人免费在线观看| 日韩一级在线| 国产麻豆精品在线观看| 久久久亚洲午夜电影| 亚洲精品久久久久久一区二区 | 欧美精品久久99久久在免费线| 日韩亚洲不卡在线| 久久电影一区| 亚洲精品国产视频| 国产精品丝袜久久久久久app| 久久久免费精品| 日韩视频中文字幕| 久久一区二区三区国产精品| av成人天堂| 国产在线视频欧美| 欧美激情在线有限公司| 午夜一区二区三区在线观看 | 久久精品99国产精品| 亚洲国产精品免费| 久久精品五月| 亚洲私人影院| 亚洲福利视频一区| 国产精品一区二区视频| 欧美国产丝袜视频| 久久久久久网| 亚洲欧美日韩另类精品一区二区三区| 欧美成人免费观看| 欧美在线黄色| 亚洲一区三区电影在线观看| 亚洲国产免费| 国产一区日韩一区| 国产精品久久久久久久7电影 | 国产精品国产三级国产aⅴ入口 | 亚洲婷婷综合色高清在线 | 久久九九热re6这里有精品| 99re8这里有精品热视频免费 | 亚洲高清不卡一区| 国产日韩欧美一区| 国产精品白丝jk黑袜喷水| 欧美电影电视剧在线观看| 久久久久久久久久久成人| 亚洲一区二区在线免费观看视频|