「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)
文章目錄
- 「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)
-
- @[toc]
- 一、概述
- 二、堵塞IO(BIO)
- 三、堵塞IO(NIO)
- 參考
- @[toc]
- 一、概述
- 二、堵塞IO(BIO)
- 三、堵塞IO(NIO)
- 參考
一、概述
在《UNIX網絡程式設計》一書中,總結歸納了5種IO模型:
- 阻塞IO(Blocking IO) (Linux下的I/O操作預設是阻塞I/O,即open和socket建立的I/O都是阻塞I/O)
- 非阻塞IO(Nonblocking IO)(可以通過fcntl或者open時使用O_NONBLOCK參數,将fd設定為非阻塞的I/O)
- IO多路複用(IO Multiplexing) (I/O多路複用,通常需要非阻塞I/O配合使用)
- 信号驅動IO(Signal Driven IO) (SIGIO)
- 異步IO(Asynchronous IO)
-
和阻塞IO
非阻塞IO
這兩個概念是
程式級别
的。主要描述的是程式請求作業系統IO操作後,如果IO資源沒有準備好,那麼程式該如何處理的問題: 前者等待;後者繼續執行(并且使用線程一直輪詢,直到有IO資源準備好了)
-
和同步IO
非同步IO
這兩個概念是
作業系統級别
的。主要描述的是作業系統在收到程式請求IO操作後,如果IO資源沒有準備好,該如何響應程式的問題: 前者不響應,直到IO資源準備好以後;後者傳回一個标記(好讓程式和自己知道以後的資料往哪裡通知),當IO資源準備好以後,再用事件機制傳回給程式。
二、堵塞IO(BIO)
BIO就是: blocking IO。最容易了解、最容易實作的IO工作方式,應用程式向作業系統請求網絡IO操作,這時應用程式會一直等待;另一方面,作業系統收到請求後,也會等待,直到網絡上有資料傳到監聽端口;作業系統在收集資料後,會把資料發送給應用程式;最後應用程式受到資料,并解除等待狀态。
應用程式想要去讀取資料,他是無法直接去讀取磁盤資料的,他需要先到核心裡邊去等待核心操作硬體拿到資料,這個過程就是1,是需要等待的,等到核心從磁盤上把資料加載出來之後,再把這個資料寫給使用者的緩存區,這個過程是2,如果是阻塞IO,那麼整個過程中,使用者從發起讀請求開始,一直到讀取到資料,都是一個阻塞狀态。
具體流程如下圖:
使用者去讀取資料時,會去先發起recvform一個指令,去嘗試從核心上加載資料,如果核心沒有資料,那麼使用者就會等待,此時核心會去從硬體上讀取資料,核心讀取資料之後,會把資料拷貝到使用者态,并且傳回ok,整個過程,都是阻塞等待的,這就是阻塞IO
總結如下:
顧名思義,阻塞IO就是兩個階段都必須阻塞等待:
階段一:
- 使用者程序嘗試讀取資料(比如網卡資料)
- 此時資料尚未到達,核心需要等待資料
- 此時使用者程序也處于阻塞狀态
階段二:
- 資料到達并拷貝到核心緩沖區,代表已就緒
- 将核心資料拷貝到使用者緩沖區
- 拷貝過程中,使用者程序依然阻塞等待
- 拷貝完成,使用者程序解除阻塞,處理資料
可以看到,阻塞IO模型中,使用者程序在兩個階段都是阻塞狀态。
三、堵塞IO(NIO)
顧名思義,非阻塞IO的recvfrom操作會立即傳回結果而不是阻塞使用者程序。
階段一:
- 使用者程序嘗試讀取資料(比如網卡資料)
- 此時資料尚未到達,核心需要等待資料
- 傳回異常給使用者程序
- 使用者程序拿到error後,再次嘗試讀取
- 循環往複,直到資料就緒
階段二:
- 将核心資料拷貝到使用者緩沖區
- 拷貝過程中,使用者程序依然阻塞等待
- 拷貝完成,使用者程序解除阻塞,處理資料
可以看到,非阻塞IO模型中,使用者程序在第一個階段是非阻塞,第二個階段是阻塞狀态。雖然是非阻塞,但性能并沒有得到提高。而且忙等機制會導緻CPU空轉,CPU使用率暴增。
參考
黑馬程式員