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