IO模型

前言

參考《UNIX Network Programming Volume 1, ThirdEdition [Electronic resources] : The Sockets Networking API》
進程運行狀態分爲內核態和用戶態兩種。
對於文件讀取:
第一步:等待數據準備
第二步:將數據從內核空間複製到用戶空間中
對於socket:
第一步:等待網絡上的數據到達,然後被複制到內核空間
第二步:將數據從內核空間複製到用戶空間中


同步與異步

同步與異步關注的是進程與內核的交互。同步進程觸發IO並等待或者輪詢IO是否完成。 異步進程觸發IO後直接返回,IO交給內核來處理,完成後內核通知進程IO完成。


 阻塞與非阻塞

阻塞和非阻塞關注的是進程在等待調用結果時的狀態。阻塞是指調用結果返回之前,當前進程會被掛起。非阻塞則相反,當前進程不會被掛起。同步有阻塞和非阻塞之分,異步沒有,它一定是非阻塞的。

 

阻塞IO模型


進程執行recvfrom系統調用後進程阻塞,等待數據準備好,此時進程讓出CPU。當數據準備好後,等待內核將數據複製到用戶空間。複製完成後,recvfrom系統調用返回成功,進程解除阻塞。此模型特點是IO過程的兩步都會等待。


非阻塞IO模型


進程執行recvfrom系統調用,如果數據還沒有準備好,那麼recvfrom系統調用返回一個錯誤。這個過程一直重複,直到數據準備好後,等待內核將數據複製到用戶空間。複製完成後,recvfrom系統調用返回成功。此模型特點是,IO過程的第一步不需要等待,而是進程需要不斷地詢問內核數據是否準備好,此時進程不會讓出CPU,而會一直佔用CPU,浪費了大量的CPU資源,因此不常用。


多路複用IO模型


進程執行select系統調用後,進程阻塞。內核監控多個套接字,當某個套接字數據準備好了,則select系統調用返回。此時進程發起recvfrom系統調用,內核將數據複製到用戶空間。複製完成後,recvfrom系統調用返回成功。此模型特點是,對於單個IO操作,和阻塞IO相比並沒有什麼不同。事實上,還更差一些。因爲這裏需要使用兩個系統調用(select 和 recvfrom),而阻塞IO只調用了一個system call (recvfrom)。不過它適合於同時處理多個IO操作,當其中的任意一個進入可讀狀態,select系統調用就可以返回。在非阻塞IO中,不斷地詢問socket狀態是通過用戶進程去進行的,而在多路複用IO中,輪詢每個socket狀態是內核在進行的,這個效率要比用戶進程高的多。


信號驅動IO模型


在信號驅動IO模型中,給某個的IO操作註冊一個信號處理函數,進程發起sigaction系統調用,等待數據準備好,此時並不會阻塞,用戶進程可以執行別的任務。當內核數據準備好了,就會發送一個信號給用戶進程,用戶進程接收到信號之後,便在信號處理函數中執行recvfrom系統調用,內核將數據複製到用戶空間。複製完成後,recvfrom系統調用返回成功。這個模型並不是真正的異步,因爲用戶進程還要執行recvfrom系統調用,這一步需要等待。


異步IO模型


進程執行aio_read系統調用,該系統調用立即返回。具體的數據準備和複製全部由內核來完成,用戶進程可以執行別的任務。

總結

其中多路複用和信號驅動,在處理業務邏輯上可以說有異步,但在IO操作層面上來說還是同步的。posix.1嚴格定義的異步IO是要求沒有任何一點阻塞,而上述的前面四個(阻塞IO,非阻塞IO,IO複用,信號驅動)都不同程度阻塞了,而且都有一個共同的阻塞: 內核拷貝數據到進程空間的這段時間需要等待。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章