對於linux socket與epoll配合相關的一些心得記錄)

來源:互聯網
上載者:User

沒有多少高深的東西,全當記錄,雖然簡單,但是沒有做過測試還是挺容易讓人糊塗的

     int nRecvBuf=32*1024;//設定為32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
1、通過上面語句可以簡單設定緩衝區大小,測試證明:跟epoll結合的時候只有當單次發送的資料全被從緩衝區讀完畢之後才會再次被觸發,多次發送資料如果沒有讀取完畢當緩衝區未滿的時候資料不會丟失,會累加到後面。
2、 如果緩衝區未滿,同一串連多次發送資料會多次收到EPOLLIN事件。
單次發送資料>socket緩衝區大小的資料資料會被阻塞分次發送,所以迴圈接收可以用ENLIGE錯誤判斷。
   3、如果緩衝區滿,新發送的資料不會觸發epoll事件(也無異常),每次recv都會為緩衝區騰出空間,只有當緩衝區空閑大小能夠再次接收資料epollIN事件可以再次被觸發
接收時接收大小為0表示用戶端斷開(不可能有0資料包觸發EPOLLIN),-1表示異常,針對errorno進行判斷可以確定是合理異常還是需要終止的異常,>0而不等於緩衝區大小表示單次發送結束。
   4、 如果中途臨時調整接收緩衝區大小,並且在上一次中資料沒有完全接收到使用者空間,資料不會丟失,會累加在一起

所以總結起來,系統對於資料的完整性還是做了相當的保正,至於穩定性沒有作更深一步的測試

   新增加:
   5、如果主accept監聽的soctet
fd也設定為非阻塞,那麼單純靠epoll事件來驅動的伺服器模型會存在問題,並發壓力下發現,每次accept只從系統中取得第一個,所以如果恰馮多個
串連同時觸發server
fd的EPOLLIN事件,在返回的event數組中體現不出來,會出現丟失事件的現象,所以當用ab等工具簡單的壓載就會發現每次都會有最後幾條資訊得
不到處理,原因就在於此,我現在的解決辦法是將server fd的監聽去掉,用一個線程阻塞監聽,accept成功就處理檢測client
fd,然後在主線程迴圈監聽client事件,這樣epoll在邊緣模式下出錯的機率就小,測試表明效果明顯
6、對於SIG部分訊號還是要做屏蔽處理,不然對方socket中斷等正常事件都會引起整個服務的退出
7、sendfile(fd, f->SL->sendBuffer.inFd, (off_t
*)&f->SL->sendBuffer.offset,
size_need);注意sendfile函數的地三個變數是傳送地址,位移量會自動增加,不需要手動再次增加,否則就會出現檔案傳送丟失現象
8、單線程epoll驅動模型誤解:以前我一直認為單線程是無法處理web伺服器這樣的有嚴重網路延遲的服務,但nginx等優秀伺服器都是機遇事件驅動
模型,開始我在些的時候也是擔心這些問題,後來測試發現,當client
socket設為非阻塞模式的時候,從讀取資料到解析http協議,到發送資料均在epoll的驅動下速度非常快,沒有必要採用多線程,我的單核
cpu(奔三)就可以達到10000page/second,這在公網上是遠遠無法達到的一個數字(網路延遲更為嚴重),所以單線程的資料處理能力已經很
高了,就不需要多線程了,所不同的是你在架構伺服器的時候需要將所有阻塞的部分拆分開來,當epoll通知你可以讀取的時候,實際上部分資料已經到了
socket緩衝區,你所讀取用的事件是將資料從核心空間拷貝到使用者空間,同理,寫也是一樣的,所以epoll重要的地方就是將這兩個延時的部分做了類似
的非同步處理,如果不需要處理更為複雜的業務,那單線程足以滿足1000M網卡的最高要求,這才是單線程的意義。
   
我以前構建的web伺服器就沒有理解epoll,採用epoll的邊緣觸發之後怕事件丟失,或者單線程處理阻塞,所以自己用多線程構建了一個任務調度器,
所有收到的事件統統壓進任無調度器中,然後多任務處理,我還將read和write分別用兩個調度器處理,並打算如果中間需要特殊的耗時的處理就增加一套
調度器,用少量線程+epoll的方法來題高效能,後來發現read和write部分調度器是多餘的,epoll本來就是一個事件調度器,在後面再次緩衝
事件分部處理還不如將epoll設為水平模式,所以多此一舉,但是這個調度起還是有用處的
  
上面講到如果中間有耗時的工作,比如資料庫讀寫,外部資源請求(檔案,socket)等這些操作就不能阻塞在主線程裡面,所以我設計的這個任務調度器就有
用了,在epoll能處理的事件驅動部分就借用epoll的,中間部分採用模組化的設計,用函數指標達到面相對象語言中的“委託”的作用,就可以滿足不同
的需要將任務(fd標識)加入調度器,讓多線程迴圈執行,如果中間再次遇到阻塞就會再次加入自訂的阻塞器,檢測完成就加入再次存入調度器,這樣就可以將
多種複雜的任務劃分開來,相當於在處理的中間環節在自己購置一個類似於epoll的事件磁碟機
   
9、多系統相容:我現在倒是覺得與其構建一個多作業系統都支援的伺服器不如構建特定系統的,如果想遷移再次改動,因為一旦兼顧到多個系統的化會大大增加系
統的複雜度,並且不能最優效能,每個系統都有自己的專屬的最佳化選項,所以我覺得遷移的工作量遠遠小於兼顧的工作量
10模組化編程,雖然用c還是要講求一些模組化的設計的,我現在才發現幾乎面相對想的語言所能實現的所有進階特性在c裡面幾乎都有對應的解決辦法(暫時發現除了操作符重載),所有學過進階面相對象的語言的朋友不放把模式用c來實現,也是一種樂趣,便於維護和自己閱讀
   11、養成注釋的好習慣

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.