linux多線程socket編程一些心得

來源:互聯網
上載者:User

    在ningx(有人用他同時保持了3萬個處理串連)上的到了一些體會,這些不僅使用於web這樣模型的server,同樣適合於所有其他的比如遊戲、ftp伺服器等。
    維持高線上人數的關鍵問題在於事件處理模型需要m:n,m遠<n, m為socket,n為串連socket,不管你有多少個cpu(比如2cpu 4核),電腦能同時處理的線程數都是很少的,socket的關鍵在於網路等IO的延遲,如果讓線程堵塞在一個網路IO上那所有的基礎最佳化演算法都是白搭,因為演算法的不佳只能影想很短的時間,但是網路IO延遲就很難講了,有位前輩說了很好的一句話:做多伺服器網路協作程式任何時候記住減少一次路由比最佳化100次一個演算法都划算
   nginx的做法是將處理常式嚴格區分開來(本次我作的Flower web server也是基於此原理),等待epoll等事件通知,他在全域範圍內維護了兩個鏈表,一個讀連表,一個寫鏈表,epoll等系統網路通知通知了某個socket可操作後他便將狀態儲存在相應的變數裡面,然後採取m個線程輪詢執行任務,這樣線程就不用等待網路io堵塞,正常的一個read socket資料需要迴圈,直到資料讀完或者產生錯誤,但我的處理不是這樣的,我在全域範圍內維護一個統一的socket fd表,這是linux的特性決定的,因為linux的socket fd是從很小的值開始的,並且同一時間內不會重複(估計內部有線程鎖),所有fd本身就是一個重要的標識量,並且一個大的fd釋放後還會從小的開始重複利用,winsows下的就不一樣,他是一個長長的指標,所有我的全域狀態表就需要一個用fd作為索引的標識就可以了,最大的fd也就是同時保持線上人數的大體數字,我設定了一個20000的狀態表,暫用棧記憶體很小,基本上不會被用完。
     然後我同樣對read和write設定兩個獨立的狀態鏈表,用m個線程來處理,所不同的是這兩個表只有一個fd項,其餘的資料都是儲存在堆分配的全域狀態表中,我對全域狀態表設定很多的狀態值,比如:read write readed writed needRepetRead needrepetWrite restart等等,這樣我可以將其他的處理分別用新的狀態鏈表來保持,鎖不同的是全域表的狀態不一樣,從而達到多個處理常式協作的問題,互斥鎖只存在於各個處理環節,如果讀的環節慢了就可以加大讀的線程數,寫的慢了可以加大寫的,處理的過程慢了可以加大處理的,這樣方便系統後期調試最佳化,但是每一個環節都不會影響全域表的處理,不會因為一個線程堵塞或則死掉導致全域的狀態都沒法進行

   初步作出來的模型同樣採用sendfile +epoll情況下,經測試我的server已經略微超過nginx,下面就是進一步的規範和最佳化擴充的部分了

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.