IOCP浅析
這一年半來一直在做游戲項目邏輯層,學會了不少東西,覺得自己應該看看服務器底層的東西了,主要的東西就是網絡模塊,網絡模塊是沿用以前項目的,在?我們項目中被我們頭改動過幾次,現在還是比較穩定的。因為是Windows平臺,所以用的依然是被大多數人神話了的IOCP,不過的確IOCP?表現的非常不錯。
什么是IOCP?
眾所周知,為了絕對同步,所以很多模式都采用的是同步模式,而不是異步,這樣就會產生很大情況下在等待,CPU在切換時間片,從而導致效率比較低。自從MS在winsocket2中引入了IOCP這個模型之后,他才開始被大家所認知。
IOCP?(I/O?Completion?Port),中文譯作IO完成端口,他是一個異步I/O操作的API,他可以高效的將I/O事件通知給我們的應用程序,那游戲項目來說,就是客戶端或者服務器。
他與Socket基礎API??select()或其他異步方法不同的是,他需要講一個Socket和一個完成端口綁定在一起,然后就可以進行網路通信了。
什么是同步/異步?
所謂同步,就是在發出一個功能調用時,在沒有得到結果之前,該調用就不返回。按照這個定義,其實絕大多數函數都是同步調用(例如sin,?isdigit等)。
異步的概念和同步相對。當一個異步過程調用發出后,調用者不能立刻得到結果。實際處理這個調用的部件在完成后,通過狀態、通知和回調來通知調用者。
邏輯上通俗來講是完成一件事再去做另外一件事情就是同步,而一起做兩件或者兩件以上的事情就是異步了。類似于Win32API中的SendMessage()和PostMessage(),你可以將他理解成單線程和多線程的區別。
拿游戲服務器與客戶端通信來說:
如果是同步:
ClientA發送一條Msg1Req消息給Server,這個時候ClientA就會等待Server處理Msg1Req。這段時間內ClientA只有等待,因為Server還沒有給ClientA回復Msg1Ack消息,所以ClientA只能癡癡的等,等到回復之后,才能處理第二條Msg2Req消息,這樣無疑就會大大的降低性能,產生非常差的用戶體驗。
如果是異步:
ClientA發送一條Msg1Req消息給Server,ClientA有發送第二條Msg2Req消息給Server,Server會將他們都存入隊列,一條一條處理,處理完之后回復給ClientA,這樣用戶就可以不必等待,效率就會非常高。
什么是阻塞/非阻塞?
阻塞調用是指調用結果返回之前,當前線程會被掛起。函數只有在得到結果之后才會返回。可能阻塞和同步有點類似,但是同步調用的時候線程還是激活的,而阻塞時線程會被掛起。
非阻塞調用和阻塞的概念相對應,指在不能立刻得到結果之前,該函數不會阻塞當前線程,而會立刻返回。
對象的阻塞模式和阻塞函數調用
對象是否處于阻塞模式和函數是不是阻塞調用有很強的相關性,但是并不是一一對應的。阻塞對象上可以有非阻塞的調用方?式,我們可以通過一定的API去輪詢狀態,在適當的時候調用阻塞函數,就可以避免阻塞。而對于非阻塞對象,調用特殊的函數也可以進入阻塞調用。函數?select就是這樣的一個例子。
對IOCP的評價如何?
I/O完成端口可能是Win32提供的最復雜的內核對象。?Jeffrey?Richter
這是實現高容量網絡服務器的最佳方法。Microsoft?Corporation
完成端口模型提供了最好的伸縮性。這個模型非常適用來處理數百乃至上千個套接字。Anthony?Jones?&?Jim?Ohlund
I/O?completion?ports特別顯得重要,因為它們是唯一適用于高負載服務器[必須同時維護許多連接線路]的一個技術。Completion?ports利用一些線程,幫助平衡由I/O請求所引起的負載。這樣的架構特別適合用在SMP系統中產生的”scalable”服務器。?Jim?Beveridge?&?Robert?Wiener
IOCP中的完成是指什么意思?
網絡通信說白了就是將一堆數據發過來發過去,到底還是數據的操作。不過大家都知道I/O操作是非常慢的,包括打印機、調制解調器、硬盤等,至少相對于CPU來說是非常慢的。坐等I/O是很浪費時間的事情,可能你只需要讀取100KB的數據,假設讀了0.1秒,假設CPU是3.0G?Hz,那么CPU已經運行了0.3G次了,所以CPU這個時候就不滿意了,哥這么NB,為什么要等你?
所以我們用另外一個線程來處理I/O操作,使用重疊IO(Overlapped?I/O)技術,應用程序可以要求OS為其傳輸數據,在完成的時候通知應用程序,然后在進行相應操作,這也就是為什么叫完成的原因。這可以使得應用程序在I/O傳輸期間可以做其他事情,這也可以最大限度的利用線程,而讓最NB的CPU不至于癡癡等待。
總結
- 上一篇: IOCP本质论
- 下一篇: WinSock2编程之打造完整的SOCK