Unix網絡編程 I/O模型

阻塞式I/O模型

默認情況下,所有的套接字都是阻塞式的。
在這裏插入圖片描述
上圖以recvfrom爲例子展示阻塞式I/O。引用程序調用recvfrom系統調用。此時內核中沒有數據準備好,於是應用程序被阻塞於recvfrom,進程進入sleep狀態。直到內核的緩衝區中準備好了數據,內核緩衝區中的數據將被複制到應用程序緩衝中,複製完成之後,recvfrom纔會返回成功。

非阻塞式I/O模型

進程將套接字設置爲非阻塞是在通知內核,當所請求的I/O操作非得吧本進程投入睡眠才能完成時,不要吧本程序投入睡眠,而是返回一個錯誤。
在這裏插入圖片描述
上圖中應用程序反覆調用recvfrom系統調用。當內核未準備好,進程並不會阻塞,也不會sleep,而是recvfrom直接返回了一個EWOULDBLOCK錯誤。當然此時你就可以調用其他函數了,圖中繼續調用了recvfrom直到內核中的數據準備好了,纔將內核緩衝數據複製到應用程序緩衝,recvfrom返回成功。

I/O複用模型

IO複用可以同時關注多個套接字的I/O。我們以select爲例子。
在這裏插入圖片描述
在這張圖之前,我們會先告訴select我們所關心的套接字,select會接收相關套接字的I/O信息。
我們調用select系統調用,當內核內無任何套接字的數據準備好時,select會阻塞,直到某些數據到來。當數據到來時,select會記錄那些套接字的數據來了(存在一個數組中)。此時就可以使用recvfrom接收相關套接字的數據,recvfrom將內核緩衝區數據複製到應用程序緩衝區後返回成功。

信號驅動式I/O模型

在這裏插入圖片描述
使用信號驅動式I/O我們首先要開啓套接字的信號驅動式I/O功能,並通過sigaction系統調用建立一個信號處理程序,該系統調用將立即返回。進程會繼續做自己的工作。當內核中的數據準備好時,內核會發送一個SIGIO信號,我們隨後就可以調用recvfrom,將內核緩衝區中的數據複製到應用程序緩衝區,並放回成功。

異步I/O模型

在這裏插入圖片描述
應用程序調用aio_read函數(POSIX異步I/O函數以aio_或lio_開頭),給內核傳遞文件描述符,緩衝區指針,緩衝區大小和文件偏移。該系統調用立即返回。應用程序繼續去做其他事情,不被阻塞。然後,內核會等待數據準備完成,然後將數據拷貝到用戶內存,當這一切都完成之後,內核會給應用程序進程發送一個signal,告訴它read操作完成了。

總結和對比

同步I/O操作:導致請求進程阻塞,直到I/O操作完成。
異步I/O操作:不導致請求進程阻塞。
前四種I/O模型,阻塞式,非阻塞式,I/O複用以及信號驅動式都屬於同步I/O。
在這裏插入圖片描述

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