視頻教程請關注 http://edu.csdn.net/lecturer/lecturer_detail?lecturer_id=440
網絡通訊,一個不朽的話題,今天和一個做游戲的朋友(以前的同事聊天),他向我訴說了他的痛苦
他之前是做客戶端的,無奈人力資源緊張,也開始搞服務器,他說自己的服務器總是不穩定,於是就
聊到了這個話題,在他現有的項目中,大概有1000個鏈接,每個連接每秒發最大發送四個數據包。而且
數據包的大小很小。服務器在做壓力測試的時候,幾乎啥都沒有做,就是接到包,然后回復,其他的
任務業務邏輯也沒有,連續測試4天,服務器就掛了。
經過了解,他在開發過程中,用來很線程,他覺得服務器一定要多線程來接受數據才快。服務器為
那么多人提供服務,一定要多線程才可以,否則cpu會忙不過來,他的想法也是大多數人的想法,其實
這就錯了。
我們可以想像一下,網卡能處理多少數據,很多程度上受限制與網絡速度,一但網絡的速度確定了,
基本上就沒有什么懸念了,例如一個100M帶寬的網絡,換算成大B,也就12M的樣子,如果一個包大小
為1K,那么一秒中,我們處理的包數量為 12 * 1024 一萬多個包,如果是一個包圍100個字節,我們
需要處理的包12W(1024 × 1024 × 12 /100)的樣子,成熟一點的網絡底層通訊庫都可以做到這一點,大可不必擔心處理不過來。
可以試想一下,使用一個單獨的線程來接收這些數據包,和使用兩個,或者多個線程處理接收這些
數據包,哪一個時間會更加快呢 ?答案肯定是一個線程接收的快。下面我們來分析下原因,為什么一個
線程會更快,先看單線程的情況:
每次接收不需要做任何的互斥處理,接收就是了,相當於該線程只接受數據,其他的事情都沒有做
但是如果是多線程接收:那么就要考慮互斥等問題,如果一個線程正在就誒收一個數據包,那么另外一個線程就不能
工作,等待第一個完成以后,才可以繼續工作,cpu會花費更多的時間在線程的互斥上,實際上相當於一個線程在工作
而不是同時有兩個或者多個線程同時工作,而且除了接收數據,還要兼顧線程切換工作。
那有些人可能會說了,這個很不對,windows中的IOCP(完成端口)就是多線程工作的,而且建議使用
多線程,IOCP確實是多線程工作的,但不是接收數據,當我們調用IOCP的”GetQueuedCompletionStatus"函數的時候,其實數據已經
完成接收了,而我們在線程做到是做已經接收到的數據做什么處理,已經是業務的事情。
而實際上,接收網絡數據包的時間遠比處理業務的時間要短,所以在我們接收到網絡數據包以后,做到事情可以並行化
如果可以並行化,那么就大大的提高了應用成的性能,舉一個簡單的例子,當客戶端要求計算一個數據的時候,這個計算
需要花費1秒鍾,那么如果我們在接收線程中處理這個事情,其他的請求將被阻塞,如下圖所示:
但如果是把計算任務放到另外的線程中,效果完全不一樣(這個另外的線程,我們給他起個名稱)叫業務線程,
當然可以用線程池的方式,這個就和IOCP(完成端口),是一回事情了。今天就說到這里,限於本人能力有限,
表述不正確的請見諒指正。