天天看點

「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)

「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)

文章目錄

  • 「網絡模型」堵塞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,那麼整個過程中,使用者從發起讀請求開始,一直到讀取到資料,都是一個阻塞狀态。

「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)

具體流程如下圖:

使用者去讀取資料時,會去先發起recvform一個指令,去嘗試從核心上加載資料,如果核心沒有資料,那麼使用者就會等待,此時核心會去從硬體上讀取資料,核心讀取資料之後,會把資料拷貝到使用者态,并且傳回ok,整個過程,都是阻塞等待的,這就是阻塞IO

總結如下:

顧名思義,阻塞IO就是兩個階段都必須阻塞等待:

階段一:

  • 使用者程序嘗試讀取資料(比如網卡資料)
  • 此時資料尚未到達,核心需要等待資料
  • 此時使用者程序也處于阻塞狀态

階段二:

  • 資料到達并拷貝到核心緩沖區,代表已就緒
  • 将核心資料拷貝到使用者緩沖區
  • 拷貝過程中,使用者程序依然阻塞等待
  • 拷貝完成,使用者程序解除阻塞,處理資料

可以看到,阻塞IO模型中,使用者程序在兩個階段都是阻塞狀态。

「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)

三、堵塞IO(NIO)

顧名思義,非阻塞IO的recvfrom操作會立即傳回結果而不是阻塞使用者程序。

階段一:

  • 使用者程序嘗試讀取資料(比如網卡資料)
  • 此時資料尚未到達,核心需要等待資料
  • 傳回異常給使用者程序
  • 使用者程序拿到error後,再次嘗試讀取
  • 循環往複,直到資料就緒

階段二:

  • 将核心資料拷貝到使用者緩沖區
  • 拷貝過程中,使用者程序依然阻塞等待
  • 拷貝完成,使用者程序解除阻塞,處理資料

可以看到,非阻塞IO模型中,使用者程序在第一個階段是非阻塞,第二個階段是阻塞狀态。雖然是非阻塞,但性能并沒有得到提高。而且忙等機制會導緻CPU空轉,CPU使用率暴增。

「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)「網絡模型」堵塞IO(BIO)與非堵塞IO(NIO)

參考

黑馬程式員

繼續閱讀