Windows高效通訊模型之IOCP

2021-07-31 09:53:06 字數 1380 閱讀 9469

今晚複習計網去了...然後思考了一下怎麼解決今天下午那份**,客戶端被子執行緒阻塞的問題。就像之前說的,那份**是「one-thread-per-client「的模型,對每個是客戶端的連線請求,都要臨時建立乙個socket來處理,這樣就造成了系統開銷比較大的問題,而且執行緒之間的互相阻塞也是影響效率的重要原因。

於是上網找了一下相關的資訊,發現windows下有一種號稱效能最好的通訊模型,叫做iocp,中文名稱叫做完成埠模型。一開始聽到這個名字也是雲裡霧裡,為啥埠會和高效處理高併發任務請求扯上關係,難道是埠還有什麼不為人知的秘密嗎?

後來看了這份教程 裡面講得比較快詳細了,這裡總結一下。

先拿目前的模型來開刀,每個執行緒處理乙個客戶端的連線請求,首先是沒有辦法處理大量的連線請求,比如我現在有10萬個連線請求,伺服器端這邊就要建立對應的socket,顯然這個開銷是無法接受的。再者,這樣的操作會導致cpu不斷地進行上下文切換,這就會導致cpu的負載非常之大,顯然也是不現實的。我們姑且稱這種方式是」阻塞通訊+多執行緒「,缺點是開銷太大,對cpu不友好,阻塞操作太多,會導致使用者體驗很差。

那麼我們就需要一種非同步處理網路操作的模型,它的核心作用是在非同步處理網路操作,使得cpu在網路操作執行的時候可以去執行別的任務,直到網路操作完成,再去獲取處理後的資料。這裡就用到了iocp模型。

具體的介紹再上面貼的教程連鏈結裡面已經寫得很詳細了,說白了,iocp的核心思想跟作業系統裡面引入的中斷有點類似(這個比喻可能不恰當,但是在整個學習過程中我對iocp的效果一直有一種既視感)。在執行i/o操作時,cpu不需要忙等待,一直輪詢裝置是否需要執行i/o操作,而是採用中斷的機制,只有當產生i/o操作的時候才通知cpu去處理,其他時間cpu可以執行別的業務。

而iocp的核心就在於維護乙個公共的訊息佇列。首先建立2*cpu核心數的執行緒,作為worker,初始的時候它們是空閒,被掛起的。然後再開闢乙個單獨的執行緒,來監聽連線請求,每當有連線請求,就accept,並將網路操作放入訊息佇列中。此時,worker執行緒排隊從佇列中取出這些操作請求並處理。注意,整個過程中主線程是非常空閒的,完全有能力去執行其他的任務。也就是說,現在我們有一條主線程,若干條worker執行緒,還有一條監聽執行緒。主線程把網路請求扔給worker執行緒去做,自己就可以同步做別的事情,而不用被阻塞掛起,等待外部i/o完成了。而這個公共訊息佇列,就叫做」完成埠「,因為它是」完成「網路操作(屬於外部i/o)之後再通知主線程把資料拿走...大概就是這麼個模型。

實際上windows的socket庫已經提供了完整的完成埠api,我感覺只要學會呼叫各種api來搭建整個模型就夠了,至於深入的實現,可能以後工作有需要的話再去**。

看來要找個時間來改進一下整個通訊模型了...然而接下來一段時間有得忙了,嘛,不過所謂的成長就是這樣吧(真的無比渴望有個大佬帶我)...

最後附上通過阻塞式的accept操作來實現iocp模型的流程圖吧,感覺已經寫得非常清晰了:

高效通訊模型之 非同步通訊模型

非同步模型 非同步和同步 同步,就是在發出乙個功能呼叫時,在沒有得到結果前,呼叫不返回 非同步,當乙個非同步過程呼叫發出後,呼叫者不能立即得到呼叫結果,而是通過狀態,通知和 來通知呼叫者。通過檢查狀態來判斷非同步呼叫結果,效率會很低,因為需要週期性檢查狀態 函式和通知差不多 同步呼叫與阻塞呼叫 對於...

Qt之TCP通訊模型

tcp應用場合 大檔案傳輸 重要檔案傳輸等對可靠性要求較高的場合 qt 中提供的所有的 socket 類都是非阻塞的。常用於socket通訊套接字的類 qtcpserver 用於 tcp ip 通訊,作為伺服器端套接字使用 qtcpsocket 用於 tcp ip 通訊,作為客戶端套接字使用。qud...

Qt之UDP通訊模型

tcp應用場合 大檔案傳輸 重要檔案傳輸等對可靠性要求較高的場合 qt 中提供的所有的 socket 類都是非阻塞的。常用於socket通訊套接字的類 qtcpserver 用於 tcp ip 通訊,作為伺服器端套接字使用 qtcpsocket 用於 tcp ip 通訊,作為客戶端套接字使用。qud...