天天看點

Linux下的五種I/O模型

堵塞I/O(blocking I/O)

非堵塞I/O (nonblocking I/O)

I/O複用(select 和poll) (I/O multiplexing)

信号驅動I/O (signal driven I/O (SIGIO))

異步I/O (asynchronous I/O (the POSIX aio_functions))

前四種都是同步。僅僅有最後一種才是異步IO。

I/O過程分為兩個過程,資料準備和資料拷貝

堵塞I/O模型:

該模型在兩個過程中一直處于堵塞狀态,直到資料拷貝完畢,系統調用傳回.

堵塞I/O模型圖:

假設資料沒有準備好,那麼系統就處于等待狀态。

當資料準備好後。将資料從系統緩沖區拷貝到使用者空間。然後該函數傳回。

在套接應用程式中。當調用recv()函數時。未必使用者空間就已經存在資料,那麼此時recv()函數就會處于等待狀态。

非堵塞I/O在第一個過程中會進行多次調用系統調用(假設資料沒有準備好的話)并馬上傳回.在資料拷貝過程中,仍然處于堵塞狀态.       

       我們把一個SOCKET接口設定為非堵塞就是告訴核心,當所請求的I/O操作無法完畢時,不要将程序睡眠。而是傳回一個錯誤。

這樣我們的I/O操作函數将不斷的測試資料是否已經準備好。假設沒有準備好。繼續測試,直到資料準備好為止。在這個不斷測試的過程中。會耗費大量的占用CPU的時間。

有點類似于輪詢

非堵塞I/O模型圖:

      I/O複用模型經常使用的函數有select、poll和epoll,詳細的差别請查閱相關文檔。

這幾個函數也會使程序堵塞(請注意和I/O堵塞進行區分)該函數能夠監聽多個socket,看是否有socket就緒。假設就緒就傳回就緒的socket數(或者逾時傳回)。然後對就緒的socket依照相應的就緒事件進行相關的操作(讀資料或者寫資料)

I/O複用模型圖:

    首先我們同意套接口進行信号驅動I/O,并安裝一個信号處理函數,程序繼續執行并不堵塞。

當資料準備好時。程序會收到一個SIGIO信号,我們能夠在信号處理函數中調用I/O操作函數處理資料。

在兩個過程中都不會發生堵塞,直到資料拷貝完畢後收到通知。

當一個異步過程調用發出後,調用者不能立馬得到結果。實際處理這個調用的子產品在完畢I/O操作後。通過狀态或者回調來通知調用者

同步IO和異步IO的差别:資料拷貝的過程中,程序是否堵塞!

堵塞IO和非堵塞IO的差别:資料準備的過程中,程序是否堵塞!