IO多路複用:I/O是指網絡I/O,多路指多個TCP鏈接(即socket或者channel),複用指複用一個或幾個線程。意思說一個或一組線程處理多個TCP鏈接。最大優點是減小系統開銷小,沒必要建立過多的進程/線程,也沒必要維護這些進程/線程。
IO多路複用使用兩個系統調用(select/poll/epoll和recvfrom),blocking IO只調用了recvfrom;select/poll/epoll 核心是能夠同時處理多個connection,而不是更快,因此鏈接數不高的話,性能不必定比多線程+阻塞IO好,多路複用模型中,每個socket,設置爲non-blocking,阻塞是被select這個函數block,而不是被socket阻塞的。數組
select機制
基本原理:
客戶端操做服務器時就會產生這三種文件描述符(簡稱fd):writefds(寫)、readfds(讀)、和exceptfds(異常)。select會阻塞住監視3類文件描述符,等有數據、可讀、可寫、出異常 或超時、就會返回;返回後經過遍歷fdset整個數組來找到就緒的描述符fd,而後進行對應的IO操做。
優勢:
幾乎在全部的平臺上支持,跨平臺支持性好
缺點:
因爲是採用輪詢方式全盤掃描,會隨着文件描述符FD數量增多而性能降低。
每次調用 select(),須要把 fd 集合從用戶態拷貝到內核態,並進行遍歷(消息傳遞都是從內核到用戶空間)
默認單個進程打開的FD有限制是1024個,可修改宏定義,可是效率仍然慢。服務器
poll機制:
基本原理與select一致,也是輪詢+遍歷;惟一的區別就是poll沒有最大文件描述符限制(使用鏈表的方式存儲fd)。
epoll機制:
基本原理:
沒有fd個數限制,用戶態拷貝到內核態只須要一次,使用時間通知機制來觸發。經過epoll_ctl註冊fd,一旦fd就緒就會經過callback回調機制來激活對應fd,進行相關的io操做。
epoll之因此高性能是得益於它的三個函數
1)epoll_create()系統啓動時,在Linux內核裏面申請一個B+樹結構文件系統,返回epoll對象,也是一個fd
2)epoll_ctl() 每新建一個鏈接,都經過該函數操做epoll對象,在這個對象裏面修改添加刪除對應的連接fd, 綁定一個callback函數
3)epoll_wait() 輪訓全部的callback集合,並完成對應的IO操做
優勢:
沒fd這個限制,所支持的FD上限是操做系統的最大文件句柄數,1G內存大概支持10萬個句柄
效率提升,使用回調通知而不是輪詢的方式,不會隨着FD數目的增長效率降低
內核和用戶空間mmap同一塊內存實現(mmap是一種內存映射文件的方法,即將一個文件或者其它對象映射到進程的地址空間)網絡
例子:100萬個鏈接,裏面有1萬個鏈接是活躍,咱們能夠對比 select、poll、epoll 的性能表現
select:不修改宏定義默認是1024,l則須要100w/1024=977個進程才能夠支持 100萬鏈接,會使得CPU性能特別的差。
poll: 沒有最大文件描述符限制,100萬個連接則須要100w個fd,遍歷都響應不過來了,還有空間的拷貝消耗大量的資源。
epoll: 請求進來時就建立fd並綁定一個callback,主須要遍歷1w個活躍鏈接的callback便可,即高效又不用內存拷貝。多線程