I/O模型介紹

I/O介紹

I/O:

網絡IO:本質是socket讀取
磁盤IO:

每次IO,都要經由兩個階段:

第一步:將數據從磁盤文件先加載至內核內存空間(緩衝區),等待數據準
備完成,時間較長
第二步:將數據從內核緩衝區複製到用戶空間的進程的內存中,時間較短

I/O模型

Linux下的五種I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3) I/O複用(select 和poll) (I/O multiplexing)
4)信號驅動I/O (signal driven I/O (SIGIO))
5)異步I/O (asynchronous I/O (the POSIX aio_functions))

前四種都是同步,只有最後一種纔是異步IO。

同步、異步:

概念:消息的通知機制
解釋:涉及到IO通知機制;所謂同步,就是發起調用後,被調用者處理消息,必須等處理完才直接返回結果,沒處理完之前是不返回的,調用者主動等待結果;所謂異步,就是發起調用後,被調用者直接返回,但是並沒有返回結果,等處理完消息後,通過狀態、通知或者回調函數來通知調用者,調用者被動接收結果。

阻塞、非阻塞:

概念:程序等待調用結果時的狀態
解釋:涉及到CPU線程調度;所謂阻塞,就是調用結果返回之前,該執行線程會被掛起,不釋放CPU執行權,線程不能做其它事情,只能等待,只有等到調用結果返回了,才能接着往下執行;所謂非阻塞,就是在沒有獲取調用結果時,不是一直等待,線程可以往下執行,如果是同步的,通過輪詢的方式檢查有沒有調用結果返回,如果是異步的,會通知回調。

經典故事案例:

人物:老張
道具:普通水壺(水燒開不響);響水壺(水燒開發出響聲)
案例:

                       1、同步阻塞:
                             老張在廚房用普通水壺燒水,一直在廚房等着(阻塞),盯到水燒開(同步);
                       2、異步阻塞:
                             老張在廚房用響水壺燒水,一直在廚房中等着(阻塞),直到水壺發出響聲(異步),老張知道水燒開了;
                       3、同步非阻塞:
                             老張在廚房用普通水壺燒水,在燒水過程中,就到客廳去看電視(非阻塞),然後時不時去廚房看看水燒開了沒                                                           (輪詢檢查同步結果);
                       4、異步非阻塞:
                             老張在廚房用響水壺燒水,在燒水過程中,就到客廳去看電視(非阻塞),當水壺發出響聲(異步),老張就知道                                                        水燒開了。

阻塞I/O模型:

簡介:進程會一直阻塞,直到數據拷貝完成

應用程序調用一個I/O函數,導致應用程序阻塞,等待數據準備好,如果數據沒有準備好,一直等待。。數據準備好,從內核拷貝到用戶空間,I/O函數返回成功。

阻塞I/O模型圖:在調用recv()/recvfrom()函數,發生在內核中等待數據和複製數據過程。
I/O模型介紹

當調用recv()函數時,系統首先檢查是否有準備好的數據,如果數據沒有準備好,那麼系統就處於等待狀態,當數據準備好後,將數據從系統緩衝區複製到用戶空間,然後函數返回。在套接應用程序中,當調用recv()函數時,未必用戶空間就已經存在數據,那麼此時recv()函數處於等待狀態

非阻塞I/O模型:

簡介:我們把一個套接口設置爲非阻塞就是告訴內存,當所請求的I/O操作無法完成時,不要驚進程睡眠,而是返回一個錯誤,河陽I/O函數會不斷的測試數據是否準備好,沒有準備好,繼續測試,直到數據準備好爲止。在測試的過程中會佔用大量的CPU時間。

I/O模型介紹

I/O複用模型:

inux提供select/poll,進程通過將一個或多個fd傳遞給select或poll系統調用,阻塞在select操作上,這樣,select/poll可以幫我們偵測多個fd是否處於就緒狀態。

select/poll是順序掃描fd是否就緒,而且支持的fd數量有限,因此它的使用受到了一些制約。
Linux還提供一個epoll系統調用,epoll使用基於事件驅動方式代替順序掃描,因此性能更高。當有fd就緒時,立即回調函數rollback。

I/O模型介紹

信號驅動I/O

簡介:兩次調用,兩次返回 
首先允許套接口進行信號驅動I/O,並安裝一個信號處理函數,進程繼續運行並不阻塞。昂數據準備好時,進程會收到一個SIGIO信號,可以在信號處理函數中調用I/O操作函數處理數據。

I/O模型介紹

異步I/O模型:

簡介:數據拷貝的時候進程無需阻塞 
當一個異步過程調用發出後,調用者不能立刻得到結果。實際處理這個調用的部件在完成後,通過狀態,通知和回調通知調用者輸入輸出操作。

I/O模型介紹

I/O多路複用技術

I/O編程中,需要處理多個客戶端接入請求時,可以利用多線程或者I/O多路複用技術進行處理。

  正如前面的簡介,I/O多路複用技術通過把多個I/O的阻塞複用到同一個select的阻塞上,從而使得系統在單線程的情況下可以同時處理多個客戶端請求。

    與傳統的多線程模型相比,I/O多路複用的最大優勢就是系統開銷小,系統不需要創建新的額外線程,也不需要維護這些線程的運行,降低了系統的維護工作量,節省了系統資源。

    主要的應用場景:

    服務器需要同時處理多個處於監聽狀態或多個連接狀態的套接字。
    服務器需要同時處理多種網絡協議的套接字。
    支持I/O多路複用的系統調用主要有select、pselect、poll、epoll。

    而當前推薦使用的是epoll,優勢如下:

    支持一個進程打開的socket fd不受限制。
    I/O效率不會隨着fd數目的增加而線性下將。
    使用mmap加速內核與用戶空間的消息傳遞。
    epoll擁有更加簡單的API。
I/O模型介紹

I/O模型介紹

select/poll/epoll

Select:POSIX所規定,目前幾乎在所有的平臺上支持,其良好跨平臺支持也是它的一個優點,本質上是通過設置或者檢查存放fd標誌位的數據結構來進行下一步處理
缺點
1 單個進程能夠監視的文件描述符的數量存在最大限制,在Linux上一般爲1024,可以通過修改宏定義FD_SETSIZE,再重新編譯內核實現,但是這樣也會造成效率的降低
2 單個進程可監視的fd數量被限制,默認是1024,修改此值需要重新編譯內核
3 對socket是線性掃描,即採用輪詢的方法,效率較低
4 select 採取了內存拷貝方法來實現內核將 FD 消息通知給用戶空間,這樣一個用來存放大量fd的數據結構,這樣會使得用戶空間和內核空間在傳遞該結構時複製開銷大

poll

1 本質上和select沒有區別,它將用戶傳入的數組拷貝到內核空間,然後查詢每個fd對應的設備狀態
2 其沒有最大連接數的限制,原因是它是基於鏈表來存儲的
3 大量的fd的數組被整體複製於用戶態和內核地址空間之間,而不管這樣的複製是不是有意義
4 poll特點是“水平觸發”,如果報告了fd後,沒有被處理,那麼下次poll時會再次報告該fd
5 邊緣觸發:只通知一次

epoll:

在Linux 2.6內核中提出的select和poll的增強版本

1 支持水平觸發LT和邊緣觸發ET,最大的特點在於邊緣觸發,它只告訴進程哪
些fd剛剛變爲就需態,並且只會通知一次
 2 使用“事件”的就緒通知方式,通過epoll_ctl註冊fd,一旦該fd就緒,內核
就會採用類似callback的回調機制來激活該fd,epoll_wait便可以收到通知

優點:

1 沒有最大併發連接的限制:能打開的FD的上限遠大於1024(1G的內存能監聽
約10萬個端口),具體查看/proc/sys/fs/file-max,此值和系統內存大小相關
2 效率提升:非輪詢的方式,不會隨着FD數目的增加而效率下降;只有活躍可
用的FD纔會調用callback函數,即epoll最大的優點就在於它只管理“活躍”
的連接,而跟連接總數無關
3 內存拷貝,利用mmap(Memory Mapping)加速與內核空間的消息傳遞;即
epoll使用mmap減少複製開銷
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章