淺析I/O模型-select、poll、epoll

I/O流

  1. 概念

    (1)c++中將數據的輸入輸出稱之爲流(stream),在c++中,流被定義爲類,成爲流類(stream class),其定義的對象爲流對象。html

    (2)文件,套接字(socket),管道(pipe)等可以進行I/O操做的對象,能夠被看作爲流nginx

  2. 工做機制

    (1)大多數文件系統的默認I/O操做都是緩存I/O。在Linux的緩存I/O機制中,讀取數據時,都會將數據先拷貝到操做系統內核的緩衝區中,而後將操做系統內核緩衝區的數據拷貝到應用程序的地址空間,寫的過程則相反。c++

    (2)緩存I/O使用操做系統內核緩衝區,在必定程度上分離了應用程序空間和實際的物理設備,經過將數據寫入緩衝區後,再一次性處理,減小了讀盤的次數,從而提升了性能git

I/O模型

  1. 同步與異步:關注的是消息通訊機制

    同步(synchronous):調用者會一直「等待」被調用者返回消息,才能繼續執行,在此期間,調用者不能作其它事github

    異步(asynchronous):被調用者經過狀態、通知或回調機制主動通知調用者被調用者的運行狀態,在此期間,調用者能夠邊「等待」,邊作其它事編程

  2. 阻塞和非阻塞:關注調用者的狀態

    阻塞(blocking):調用者一直「等待」所處的狀態segmentfault

    非阻塞(blocking):調用者可以邊「等待」,邊作其它事的狀態數組

  3. 同步I/O

    (1)阻塞式I/O:程序發出I/O請求,若是內核緩衝區爲空,此時進行讀操做,那麼該程序就會阻塞緩存

    (2)非阻塞式I/O:程序發出I/O請求,若是內核緩衝區爲空,此時進行讀操做,此時就會馬上返回一個錯誤網絡

    (3)I/O複用

    a. 這是一種機制,程序註冊一組文件描述符給操做系統,監視多個描述符,一旦某個描述符就緒(通常是讀就緒或者寫就緒),可以通知程序進行相應的讀寫操做。表示「我要監視這些fd是否有I/O事件發生,有了就告訴程序處理」。

    b. 當多個I/O流共用一個等待機制時,該模型會阻塞進程,可是進程時阻塞在這種機制的系統調用上,不是阻塞在真正的I/O操做上

    c. I/O多路複用須要和非阻塞I/O一塊兒使用,非阻塞I/O和I/O多路複用式相對獨立的。非阻塞I/O僅僅指流對象馬上返回,不會被阻塞;而I/O多路複用只是操做系統提供的一種便利的通知機制。

    (4)信號驅動式I/O

    a. 用戶進程能夠經過系統調用註冊一個信號處理程序,而後主程序能夠繼續向下執行,當有I/O操做準備就緒時,由內核通知觸發一個SIGIO信號處理程序執行,而後將用戶進程所須要的數據從內核空間拷貝到用戶空間

    b. 此模型的優點在於等待數據報到達期間進程不被阻塞。用戶主程序能夠繼續執行,只要等待來自信號處理函數的通知。

  4. 異步I/O

    a. 程序進程向內核發送I/O調用後,不用等待內核響應,能夠繼續接受其餘請求,內核調用的I/O若是不能當即返回,內核會繼續處理其餘事物,直到I/O完成後將結果通知給內核

    b. 信號驅動式IO是由內核通知咱們什麼時候啓動一個IO操做,而異步IO是由內核通知咱們IO操做什麼時候完成。

I/O複用模型

  1. select

    select的大體工做流程:

    (1)採用數組組織文件描述符

    (2)經過遍歷數組的方式,監視文件描述符的狀態(可讀,可寫,異常)

    (3)若是沒有可讀/可寫的文件描述符,進程會阻塞等待一段事件,超時就返回

    (4)當有一個可讀/可寫的文件描述符存在時,進程會從阻塞狀態醒來

    (5)進行無差異輪詢,找出可以操做的I/O流,若處理後,會移除對應的文件描述符

    select的缺點:

    (1)每次調用select,都須要把文件描述符集合從用戶空間貝到內核空間,這個開銷在I/O流不少時會很大

    (2)同時每次調用select都須要在內核遍歷傳遞進來的所文件描述符數組,這個開銷在I/O流不少時也很大

    (3)select支持的文件描述符數量過小了,默認是1024

  2. poll

    (1)採用鏈表組織文件描述符

    (2)原理和select一致

    (3)只是解決了支持的文件描述符受限的缺點

    (4)select和poll都是水平觸發:找到可操做的I/O流並通知進程,但進程本次沒有處理,文件描述符沒有被移除,下次輪詢時依舊會通知

  3. epoll

    工做原理:

    (1)紅黑樹和就緒鏈表,紅黑樹用於管理全部的文件描述符,就緒鏈表用於保存有事件發生的文件描述符。

    (2)接收到I/O請求,會在紅黑樹查找是否存在,不存在就添加到紅黑樹中,存在則將對應的文件描述符放入就緒鏈表中

    (3)若是就緒鏈表爲空,進程則阻塞不然遍歷就緒鏈表,並通知應用進程處理文件描述符對應的I/O

    工做模式:

    (1)LT模式(水平觸發):檢測到可處理的文件描述符時,通知應用程序,應用程序能夠不當即處理該事件。後續會再次通知

    (2)ET模式(邊緣觸發):檢測到可處理的文件描述符時,通知應用程序,應用程序必須當即處理該事件。若是本次不處理,則後續再也不通知

參考資料

IO五種模型和select與epoll工做原理(引入nginx) - osc_1ont5xz2的我的空間 - OSCHINA - 中文開源技術交流社區

IO模型:同步、異步、阻塞、非阻塞 | 神奕的博客 (songlee24.github.io)

(3) io複用與epoll模型詳解_我的文章 - SegmentFault 思否

(3) Linux IO模式及 select、poll、epoll詳解_人云思雲 - SegmentFault 思否

Linux 網絡編程的5種IO模型:多路複用(select/poll/epoll) - 黃樹超 - 博客園 (cnblogs.com)

(3) 網絡編程——select模型(總結)_我的文章 - SegmentFault 思否

網絡編程之IO模型與Epoll - 簡書 (jianshu.com)

完全搞懂epoll高效運行的原理 - 簡書 (jianshu.com)

若是這篇文章說不清epoll的本質,那就過來掐死我吧! (3) - 知乎 (zhihu.com)

相關文章
相關標籤/搜索