Linux多路複用介紹

Select

首先介紹多路複用:一個進程監聽多個文件描述符,Linux中一切皆文件,也就是一個進程管理多個客戶端連接。

Select模型不斷掃描文件描述符集合

Select模型缺點:

  一個進程打開的fd(文件描述符)是有限制的,默認1024,所以select模型最大的併發數就是1024個。

  每次select調用都會線性掃描全部的fd集合,時間複雜度O(n)。

  用戶/內核空間 內存拷貝問題。

Poll和epoll

對上面三個缺點 後序的poll和epoll給出了優化

1.Poll相對Select比較,提高了可打開文件描述符的數量。一個進程打開fd的限制------>整個系統可用打開的文件數目。

在1G內存的服務器,限制是10w左右。

2.內核查找紅黑樹中ready的socket放到就緒列表,這個過程使用了內核的中斷機制。 然後複製到用戶態因爲有就緒列表

 此後 用戶態使用的時候就不需要在遍歷所有的fd,這個過程事件通知,只把準備好的fd告訴你,算是事件通知的方式。

3.和select輪詢不斷的從內核態向用戶態複製fd相比,epoll在內核態中,準備了一個就緒鏈表起到緩衝作用,一次性複製多個就緒的fd.

epoll數據結構:

  使用紅黑樹存放了所有文件描述符節點。

  使用鏈表存放就緒的文件描述符

epoll到底有沒有mmap共享內存:

epoll早期版本是沒有epoll_create、epoll_ctrl、epoll_wail這三個方法的,所以傳遞參數就用到了mmap,但是後來有了這三個方法之後,就不需要mmap了,用戶和內核直接傳遞參數的

AIO

AIO希望的是,你select,poll,epoll都需要用一個函數去監控一大堆fd,那麼我AIO不需要了,你把fd告訴內核,你應用程序無需等待,內核會通過信號等軟中斷告訴應用程序,數據來了,你直接讀了,所以,用了AIO可以廢棄select,poll,epoll。

但linux的AIO的實現方式是內核和應用共享一片內存區域,應用通過檢測這個內存區域(避免調用nonblocking的read、write函數來測試是否來數據,

因爲即便調用nonblocking的read和write由於進程要切換用戶態和內核態,仍舊效率不高)來得知fd是否有數據,可是檢測內存區域畢竟不是實時的,你需要在線程裏構造一個監控內存的循環,設置sleep,總的效率不如epoll這樣的實時通知。

所以,AIO是渣,適合低併發的IO操作。所以java7引入的NIO.2引入的AIO對高併發的網絡IO設計程序來說,也是渣,只有Netty的epoll+edge-triggered notification最牛,能在linux讓應用和OS取得最高效率的溝通。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章