I/O復用
概念
內核一旦發現進程指定的一個或者多個I/O條件就緒(也就是說輸入已準備好被讀取,或者描述符已能承受更多的輸出),它就通知進程。這個能力稱為I/O復用(I/O multiplexing)。
使用場景
當處理多個多個文件描述符或者監聽多個socket時,必須使用I/O復用。
如果一個服務器要同時處理TCP和UDP,一般要使用I/O復用。
I/O模型
阻塞式I/O模型
非阻塞式I/O模型
I/O復用(select和poll)
信號驅動式I/O模型
異步I/O模型
什麽叫數據準備好?
數據準備分兩個階段:1、等待網絡數據到達,數據被復制到內核緩沖區,即內核空間;2、把內核數據復制到用戶進程緩沖區,即用戶空間。
阻塞式I/O模型
以recvfrom系統調用為例,用戶調用recvfrom,然後切換到內核態,內核等待數據到來,此時有可能阻塞(如果網絡數據還沒到達的話)。然後網絡數據到達後將內核緩沖區數據復制到用戶空間,返回成功。這時候從內核態再切換到用戶態,處理數據報。
類似這種進程一直等待數據到來,從系統調用開始到它返回,整段時間是被阻塞的。成功返回後開始處理數據報。 (進程等待的時候是被掛起休眠麽?還是在幹嘛?)
非阻塞式I/O模型
把一個套接字或FD設置為非阻塞,就是通知內核,當數據沒準備好時,返回一個錯誤,而不是一直等待。 如果有數據準備好,則復制到用戶空間並返回成功指示。
常見的用法是用一個循環去不斷的調用recvfrom,去查看屬否有數據準備好,這種方式被稱為輪詢(polling)。應用進程持續輪詢內核,這麽做消耗大量CPU資源。所以這種模型很少見。
I/O復用模型
有了I/O復用,如select,poll,我們就可以調用select或者poll,阻塞在這兩個系統調用上,而不是阻塞在真正的I/O系統調用上。
我們調用select,等待fd或者socket變為可讀。當select返回套接字可讀這一條件時,我們再調用recvfrom把所有可讀數據從內核復制到用戶空間。
信號驅動式I/O模型
異步I/O模型
同步I/O和異步I/O的對比
同步I/O操作:請求導致進程阻塞,直到I/O操作完成;
異步I/O操作:不導致進程阻塞。
select函數
I/O復用