Linux 網絡I/O模型


前言

     本文是筆者的第一篇博文,在這篇文章的大部分內容基於steven大神的《Unix Network Programming》。一來是對書本內容的整理與歸納。二來也是為接下來的博文奠定基礎。

     在實際應用中,數據操作通常分為輸入和輸出,那么以輸入為例,在操作系統中,一個數據的輸入通常分為以下兩個過程:

  1. 等待數據准備好.
  2. 將准備好的數據從內核拷貝到用戶空間

     下面我們將會分別討論 I/O 模型中的兩個大類,即 同步 I/O 與 異步 I/O。

      圖 1. 基本I/O 模型的簡單矩陣

同步阻塞I/O

      最常用的一個模型是同步阻塞 I/O 模型。其行為非常容易理解,其用法對於典型的應用程序來說都非常有效。在調用 read 系統調用時,應用程序會阻塞並對內核進行上下文切換。然后會觸發讀操作,當響應返回時(從我們正在從中讀取的設備中返回),數據就被移動到用戶空間的緩沖區中。然后應用程序就會解除阻塞(read 調用返回)。

       圖 2. 同步阻塞 I/O 模型

 

同步非阻塞 I/O

     同步阻塞 I/O 的一種效率稍低的變種是同步非阻塞 I/O。在這種模型中,設備是以非阻塞的形式打開的。這意味着 I/O 操作不會立即完成,read操作可能會返回一個錯誤代碼,說明這個命令不能立即滿足(EAGAIN 或 EWOULDBLOCK

      圖 3. 同步非阻塞 I/O 模型

      當一個應用進程像這樣對一個非阻塞描述符循環調用recvfrom時,我們稱之為輪詢(polling)。應用進程只需輪詢內核,以查看某個操作是否就緒。這么做往往耗費大量CPU時間。

I/O復用模型

      I/O 復用有時又被稱為 事件驅動 I/O, 它的最大優勢在於,我們可以將感興趣的多個I/O事件(更精確的說,應該是 I/O 所對應的文件描述符)注冊到 select/poll/epoll/kqueue 之中某一個系統調用上(很多時候,這些系統調用又被稱為多路復用器。假設此時我們選擇了 select() )。此后,調用進程會阻塞在 select() 系統調用之上(而不是阻塞在真正的 I/O 系統調用(如 read(), write() 等)上)。select() 會負責監視所有已注冊的 I/O 事件,一旦有任意一個事件的數據准備好,那么 select() 會立即返回,此時我們的用戶進程便能夠進行數據的復制操作。

        圖 4.  I/O復用模型

     總而言之,I/O 復用的優點就在於可以同時等待多個I/O事件;而缺點是會進行兩次系統調用(一次 select(), 一次 read() )。

信號驅動式I/O模型

     在這種模型下,我們首先開啟套接字的信號驅動式I/O功能,並通過sigaction系統調用安裝一個信號處理函數。改系統調用將立即返回,我們的進程繼續工作,也就是說他沒有被阻塞。當數據報准備好讀取時,內核就為該進程產生一個SIGIO信號。我們隨后就可以在信號處理函數中調用read讀取數據報,並通知主循環數據已經准備好待處理,也可以立即通知主循環,讓它讀取數據報。

       圖 5. 信號驅動I/O模型

     無論如何處理SIGIO信號,這種模型的優勢在於等待數據報到達期間進程不被阻塞。主循環可以繼續執行,只要等到來自信號處理函數的通知:既可以是數據已准備好被處理,也可以是數據報已准備好被讀取。

異步非阻塞 I/O

     異步非阻塞 I/O 模型是一種處理與 I/O 重疊進行的模型。讀請求會立即返回,說明 read 請求已經成功發起了。在后台完成讀操作時,應用程序然后會執行其他處理操作。當 read 的響應到達時,就會產生一個信號或執行一個基於線程的回調函數來完成這次 I/O 處理過程。

      圖 6. 異步非阻塞I/O模型

      在一個進程中為了執行多個 I/O 請求而對計算操作和 I/O 處理進行重疊處理的能力利用了處理速度與 I/O 速度之間的差異。當一個或多個 I/O 請求掛起時,CPU 可以執行其他任務;或者更為常見的是,在發起其他 I/O 的同時對已經完成的 I/O 進行操作。

各種I/O模型的比較

      通過上面的討論可以清楚的看到,同步 I/O 總會有阻塞的過程,這就是“同步”最本質的特征。而如前文所說,異步 I/O 的最大特點在於用戶進程均不阻塞。 用戶進程告知內核啟動某一 I/O 操作, 並讓內核全權代為執行(包括等待數據及拷貝數據至用戶空間),此后用戶進程可以立即執行其它的任何操作。等到所有 I/O 過程執行完成后, 內核會通知用戶程。由此可見,在整個過程中,用戶進程均不阻塞。

       圖 7. 各種I/O模型的比較1

      圖 8 . I/O 模型比較2
          I/O模型                                                               讀寫操作和阻塞階段
          阻塞I/O                                                                應用阻塞於讀寫函數
          I/O復用                     應用阻塞於I/O復用系統調用,但可同時監聽多個I/O事件。對I/O本身的讀寫操作是非阻塞的
       信號驅動I/O                                     信號觸發讀寫就緒事件,用戶程序執行讀寫操作。應用沒有阻塞階段
          異步I/O                                     內核執行讀寫操作並觸發讀寫完成事件。應用沒有阻塞階段

 

 

 

 

 

參考

    《Unix Network Programming》(volume 1)

    《使用異步 I/O 大大提高應用程序的性能

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM