關於socket通訊,如何才能高效?


視頻教程請關注 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(完成端口),是一回事情了。今天就說到這里,限於本人能力有限,

表述不正確的請見諒指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM