天天看點

linux的五種I/O模型

I/O操作如何完成?

由于程序無法直接操作I/O裝置,是以必須通過系統調用請求kernel來協助完成I/O操作,核心會為每一個I/O裝置維護一個buffer。其工作流程為:

對于輸入而言,等待(wait)資料輸入至buffer中需要時間,在從buffer複制(copy)到使用者程序緩存區中也需要時間。是以,根據等待模式不同,I/O動作可以分為5種模式:

linux中的5種I/O模型

1、阻塞I/O模型

在這個模型下。當程序執行系統調用時,如果在使用者程序空間的緩存區中沒有找到相應的資料,則程序将處于阻塞狀态。當核心從磁盤上讀取資料到核心空間的buffer中,并且buffer中的資料複制到使用者程序空間的緩存區中這段時間裡,程序都将處于阻塞狀态。當資料到達使用者程序緩存區中,程序就會解除阻塞狀态,再有程序将資料傳回給用戶端。

由于程序處于阻塞狀态,是以很少占用cpu,隻是等待cpu的響應。是以,這種模型可以提高cpu的使用效率。在這種模型下,如果使用者程序空間中依然沒有資料,此時将程序喚醒,仍然沒有什麼用,是以,我們将這種睡眠叫做不可中斷睡眠。

其工作原理如圖所示:

linux的五種I/O模型

2、非阻塞I/O模型

在這種模型下。程序執行系統調用,如果在使用者程序空間緩存區中沒有找到資料,則程序不會處于阻塞狀态。而是程序不斷的詢問使用者程序空間緩存區中是否有資料。如果沒有,立即傳回EWOULDBLOCK,此時由于程序處于非阻塞狀态,是以,該程序可以做其他的事情。

在這種模型下,程序需要不斷的詢問使用者程序緩存區中是否有資料,是以,會造成cpu大量的進行上下文切換(程序切換),會大量的消耗cpu。這種模型很少被人使用。

linux的五種I/O模型

3、I/O多路複用

在這種模型下,程序會受阻于select,poll或epoll函數。這兩個函數可以阻塞多個I/O操作,可以同時對多個讀操作和多個寫操作進行檢測,直到資料變成可讀或可寫時,即資料已經加載到buffer中。才真正調用I/O操作函數,然後再将buffer中的資料複制到使用者程序緩存區中,然後程序讀取其資料,最後傳回給用戶端。

linux的五種I/O模型

4、信号驅動I/O模型

在這種模型,當核心将資料讀取到核心空間中的buffer中時,核心會為程序生成一個SIGIO信号。告知程序資料已準備好了,然後程序執行系統調用,将buffer中的資料拷貝至使用者程序緩存區中,最後程序讀取相應的資料傳回給用戶端。

linux的五種I/O模型

5、異步I/O模型

在這種模型下,資料從磁盤加載到buffer中,再将buffer中的資料複制到使用者程序緩存區。當資料複制完成後,核心會發生一個信号給程序,這樣程序會在使用者程序緩存區中讀取資料,然後再傳回給用戶端。

異步I/O模型與信号驅動I/O模型的主要差別在于;信号驅動模型是由核心告知何時啟動I/O操作;而異步I/O模型是由核心告知I/O操作何時完成。

linux的五種I/O模型

5種不同的I/O模型比較

linux的五種I/O模型

同步I/O:synchronous I/O,引起請求程序阻塞,直到I/O完成。

異步I/O:asynchronous I/O ,不導緻請求程序阻塞。 

水準觸發:隔一段時間通知一次,直到程序看到

邊緣觸發:隻發送一次通知,不管程序是否看到

程序和線程的特點

程序特點:

1、對于多程序模型而言,一個程序響應一個請求

2、程序量大,程序切換次數過多

3、每個程序的位址空間是獨立,很多空間是重複的資料,是以記憶體使用效率較低

線程特點:

1、每個線程響應一個請求:

2、線程依然切換:切換較之程序屬于輕量級

3、同一個程序的線程可以共享程序的諸多資源,比如打開的檔案;

4、對記憶體的需求較之程序略有下降;

5、快速切換時會帶來線程抖動

繼續閱讀