淺談poll/select epoll的區別

  poll/setect,epoll三個命令都是屬於內核方法,是內核實現用一個線程監聽多個連接的方法,其中epoll是Linux2.6之後引入的一種高效的連接事件監聽機制。

select原理

  select方法是將文件描述符數組從用戶控件傳入內核空間,內核通過輪詢的方式查看所有連接,如何循環一次沒有連接事件到底則等待,事件到達後返回。返回之後客戶端需要遍歷怎個數組,找出產生事件的連接。同時select默認監聽的連接數爲1024

poll原理

  poll方法與select方法類似,只不過poll使用鏈表存儲文件描述符,因此理論上沒有監聽連接數量的限制,但都是用戶空間向內核空間傳遞需要監聽的文件描述符,然後內核使用輪詢的方式查看是否有事件到達,如果沒有則等待,有則返回,返回後用戶程序仍然要遍歷所有文件描述符,找出發生事件的描述符

epoll原理

  epoll是Linux2.6對poll/select方法的改進,他是基於信號驅動的io多路複用方法。epoll由三個內核方法組成:

  1. int epoll_create(int size)
      創建一個epoll對象,size參數用於指定該對象最大內容納的連接數量,在後來的版本中,棄用了size參數
  2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
      epoll對象中有一棵紅黑樹,用來存儲被監聽的文件描述符。epoll_ctl命令用來向epoll對象中添加,刪除,修改文件描述符。epfd參數指epoll對象;op參數:EPOLL_CTL_ADD(添加操作)、EPOLL_CTL_DEL(刪除操作)、EPOLL_CTL_MOD(修改操作);
    fd參數用來指定被操作的文件描述符;event參數用來指定文件描述符關心的事件類型
  3. int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
      阻塞等待事件發生,當事件發生時,內核會調用回調方法將該文件描述符添加到返回值列表中,返回事件的數目和已經發生的事件集合,該方法可以指定等待時間,超出等待時間就直接返回
      epoll每次調用時不必向內核空間傳入整個文件描述符數組,而是通過epoll_ctl方法添加、刪除、修改部分文件描述符,同時epoll方法返回的不是整個被監聽的文件描述符數組,而是事件發生文件描述符數組。

epoll觸發方式

  1. 水平觸發(LT):對於對操作,只要緩衝器還有未讀取的數據就會觸發該事件;對於寫操作,只要緩衝區還未滿,就會返回寫就緒
  2. 邊緣觸發(ET):只要當轉態發生變化時纔會觸發事件。對於讀,只有當緩衝區有不可讀變爲可讀時才返回讀事件;對於寫,只要當緩衝區由不可寫變爲可寫是才返回寫就緒。

epoll與select、poll方法的對比

  1. 後兩者是通過輪詢的方式,每次都要遍歷整個被監聽的文件描述符數組,因此監聽效率低下,沒法實現100萬級連接的監聽,前者採用的是信號驅動,當事件發生時,調用回調函數將對應文件描述符添加到返回值數組中,避免了低效的遍歷
  2. 後兩者返回的是整個被監聽的文件描述符數組,因此每次用戶程序都需要遍歷整個數組,找出事件發生的是文件描述符,而前者返回的就是發生事件的文件描述符
  3. 後兩者存在大量的數據拷貝,每次開始都需要將整個文件描述符數組從用戶空間複製到內核空間,結束之後再從內核空間複製到用戶空間,而前者只需要操作發生變化的文件描述符,同時返回的是事件到達的那部分文件描述符
  4. epoll使用紅黑樹存儲文件描述符,實現高效的添加、刪除和修改操作
  5. epoll無需重構紅黑樹,可以沿用上次的紅黑樹
  6. epoll有高效的邊緣觸發方式,避免了由於數據未讀完或則寫緩衝區未滿而產生的重複觸發。
  7. epoll雖然效率高,但是當監聽連接少,且連接十分活躍的時候效率不一定比poll高,因爲存在很對函數回調
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章