IO多路複用之select、poll、epoll

IO多路複用是指內核一旦發現進程指定的一個或者多個IO條件準備讀取,它就通知該進程。web

與多進程和多線程技術相比,I/O多路複用技術的最大優點是系統開銷小,系統沒必要建立進程/線程,也沒必要維護這些進程/線程,從而大大減少了系統的開銷。多線程

目前支持I/O多路複用的系統調用有 select,pselect,poll,epoll,I/O多路複用就是經過一種機制,一個進程能夠監視多個描述符,一旦某個描述符就緒(通常是讀就緒或者寫就緒),可以通知程序進行相應的讀寫操做。但select,pselect,poll,epoll本質上都是同步I/O,由於他們都須要在讀寫事件就緒後本身負責進行讀寫,也就是說這個讀寫過程是阻塞的,而異步I/O則無需本身負責進行讀寫,異步I/O的實現會負責把數據從內核拷貝到用戶空間。併發

關於I/O多路複用(又被稱爲「事件驅動」),首先要理解的是,操做系統爲你提供了一個功能,當你的某個socket可讀或者可寫的時候,它能夠給你一個通知。這樣當配合非阻塞的socket使用時,只有當系統通知我哪一個描述符可讀了,我纔去執行read操做,能夠保證每次read都能讀到有效數據而不作純返回-1和EAGAIN的無用功。寫操做相似。操做系統的這個功能經過select/poll/epoll/kqueue之類的系統調用函數來使用,這些函數均可以同時監視多個描述符的讀寫就緒情況,這樣,多個描述符的I/O操做都能在一個線程內併發交替地順序完成,這就叫I/O多路複用,這裏的「複用」指的是複用同一個進程/線程。異步

在select/poll中,進程只有在調用必定的方法後,內核纔對全部監視的文件描述符進行掃描,而epoll事先經過epoll_ctl()來註冊一個文件描述符,一旦基於某個文件描述符就緒時,內核會採用相似callback的回調機制,迅速激活這個文件描述符,當進程調用epoll_wait()時便獲得通知。(此處去掉了遍歷文件描述符,而是經過監聽回調的的機制。這正是epoll的魅力所在。)socket

注意:svg

若是沒有大量的idle-connection或者dead-connection,epoll的效率並不會比select/poll高不少,可是當遇到大量的idle-connection,就會發現epoll的效率大大高於select/poll。函數

select、poll、epoll區別# 性能

  1. 支持一個進程所能打開的最大鏈接數:
    操作系統

  2. FD劇增後帶來的IO效率問題:
    線程

  3. 消息傳遞方式

綜上,在選擇select,poll,epoll時要根據具體的使用場合以及這三種方式的自身特色:

表面上看epoll的性能最好,可是在鏈接數少而且鏈接都十分活躍的狀況下,select和poll的性能可能比epoll好,畢竟epoll的通知機制須要不少函數回調。

select低效是由於每次它都須要輪詢。但低效也是相對的,視狀況而定,也可經過良好的設計改善。

參考:
https://www.jianshu.com/p/486b0965c296

相關文章
相關標籤/搜索