UNIX下IO模型分析

UNIX下IO模型分析

UNIX下的五種常見IO模型分析,幫助理解

IO操作的兩個階段

以讀數據操作爲例:
1. 等待內核數據準備(數據拷貝到內核緩衝區)
2. 將數據從內核拷貝到用戶空間

IO模型

UNIX下共有五種常見的IO模型:
UNIX下共有五種常見的IO模型

下面以recvfrom接口舉例

阻塞IO

默認情況下,所有的套接字都是阻塞的
阻塞IO
調用recvfrom接口,進程在IO操作的兩個階段都會阻塞,直到最終數據拷貝到用戶空間或者過程中出現錯誤纔會返回,進程在阻塞狀態下是不佔用CPU資源的

最常見的錯誤是發生系統中斷,此時需要重讀,可參考這裏

非阻塞IO

可以通過fcntl(sockfd,F_SETFL,O_NONBLOCK)將套接字設置成非阻塞
非阻塞IO
調用recvfrom接口,無論內核緩衝區是否有可用數據,進程都會立即返回,所以在IO操作的第一階段是非阻塞的; 若無數據可用,內核將errno設置爲爲EWOULDBLOCK或者EAGAIN,進程可以使用輪詢的方法,保證內核在數據準備好時,能立即拷貝到用戶空間; 若有則立即將數據拷貝到用戶空間,進程在數據拷貝到用戶空間即IO操作的第二階段是阻塞的;

非阻塞IO過於消耗CPU時間,將大部分時間用於輪詢

多路複用IO

多路複用系統調用:select,pollepoll,其中windows平臺不支持pollepoll,使用方法可以參考I/O 多路複用之select、poll、epoll詳解Linux select/poll和epoll實現機制對比
 多路複用IO
調用select,等待內核數據準備,所以IO操作的第一個階段,進程是阻塞的,不過是阻塞在多路複用系統調用上,而不是IO系統調用上; 當select返回套接字可讀條件時,再調用recvfrom將數據從內核拷貝到用戶空間,IO操作的第二階段,進程是阻塞的

多路複用IO和阻塞IO,在IO操作的兩個階段都是阻塞的,不過多路複用IO使用了兩個系統調用,而阻塞IO只使用了一個,所以在連接數不是很多的情況下,阻塞IO可能性能更佳; 多路複用IO的優勢在於可以同時監控多個用於IO的文件描述符。

多線程中的阻塞IO,與多路複用IO極爲相似

信號驅動IO

信號驅動IO
調用sigaction等系統調用安裝信號處理函數,並立即返回,所以IO操作的第一階段,進程是非阻塞的; 當內核數據準備好時,內核會產生一個信號,通知進程將數據從內核拷貝到用戶空間,IO操作的第二階段,進程是阻塞的

使用方法:IO的多路複用和信號驅動

異步IO

異步IO有一組以aio開頭的系統調用,使用方法可參考Linux AIO機制
異步IO
調用異步IO系統調用,給內核傳遞描述字、緩衝區指針、緩衝區大小(與read相同的三個參數)、文件偏移(與lseek類似),告訴內核當整個操作完成時如何通知我們,並立即返回,在IO操作的兩個階段,進程都不阻塞

總結

5種IO模式比較
- 同步IO和異步IO的主要區別是將數據從內核拷貝到用戶空間是否阻塞,前者會在將數據從內核拷貝到用戶空間時即IO操作的第二個階段發生阻塞,而後者則在系統調用後直接返回,直到內核發送信號通知IO操作完成,在IO操作的兩個階段都沒有阻塞
- 阻塞IO和非阻塞IO的主要區別是系統調用是否立即返回(默認將數據從內核拷貝到用戶空間即IO操作的第二個階段是立即返回的),前者會在IO操作的兩個階段完成前一直阻塞,後者在內核沒有準備好數據的情況下立即返回,即只會在IO操作的第二個階段阻塞
- 信號驅動IO和異步IO的主要區別在於前者由內核通知我們何時啓動一個IO操作,在將數據從內核拷貝到用戶空間過程中即IO操作的第一個階段依舊是阻塞的,而後者是由內核通知我們IO操作何時完成,在IO操作的兩個階段都沒有阻塞

知乎上有一個比較生動的例子可以說明這幾種模型之間的關係。

Reference

About me

forthebadge
- GitHub:AnSwErYWJ
- Blog:http://www.answerywj.com
- Email:[email protected]
- Weibo:@AnSwEr不是答案
- CSDN:AnSwEr不是答案的專欄

Creative Commons License This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
本作品採用知識共享署名-相同方式共享 4.0 國際許可協議進行許可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章