理解IO多路複用

柒墨轩發表於2024-07-19

I/O 多路複用是什麼?

  I/O 多路複用是使用者程式透過複用一個執行緒來服務多個 I/O 事件的機制,我們也可以將他說成是一個執行緒服務多個檔案描述符 fd,而 I/O 多路複用是在作業系統層面實現提供的,舉個例子:Linux 平臺下常見的 I/O 多路複用有:select、poll、epoll

剛剛提到檔案描述符 fd,那 fd 到底是什麼?有什麼作用?

  • fd 是檔案描述符,用來表示一個檔案,我們可以透過 fd 找到對應的檔案並對他進行讀寫操作
  • 可以說 fd 是一個索引值,能幫助我們索引到對應的 socket 檔案或是已經開啟的磁碟檔案

那 socket 又是什麼?

  • socket 檔案代表作業系統核心中的一段 buffer,資料從客戶端傳輸過來後,透過網路協議棧的處理,socket 檔案中儲存的就是客戶端傳來的資料,讀取 socket 檔案就能獲取到客戶端相關的資料,形象的說,socket 就像是一個能夠進行雙向資料傳輸的管道
  • 舉個例子,當客戶端和服務端建立通訊,雙方都存在一個 socket 檔案,socket 建立核心 buffer 和使用者程式的通道完成資料的傳輸

那資料到達我們的伺服器,被使用者程式讀取到,中間的過程具體是什麼樣的?

看圖:

  • 資料在客戶端進行層層包裝之後,傳輸到我們的伺服器,網路卡透過 DMA 技術將收到的 frame 寫到作業系統的核心,接著觸發 CPU 中斷,讓作業系統不斷從 buffer 中取出資料交給協議棧處理,資料在經過協議棧處理後進入 socket 檔案,所以 socket 檔案中就存在了客戶端相關的資料,我們就可以對這些資料進行讀寫操作了

什麼是 DMA 技術?

  • DMA(Direct Memory Access)用於在外設與儲存器之間以及儲存器與儲存器之間提供高速資料傳輸,可以在無需任何 CPU 操作的情況下透過 DMA 快速移動資料,這樣節省的 CPU 資源可供其它操作使用。

什麼是 frame?

  • 一個 http 報文最終會傳輸到資料鏈路層,而鏈路層(乙太網)的最基本單位是 frame,也叫做以太幀

問題來了,那為什麼需要 I/O 多路複用?

  • 剛剛我們聊到,客戶端的資料傳輸過來,進入了 socket 檔案中,當他們發生事件的時候,使用者程式需要建立執行緒進行處理
    •   一般 fd 對應兩種事件
      •     是否可以寫(緩衝區滿了,可能寫不下,註冊事件,等到可以寫了,通知我)
      •   是否可以讀(緩衝區有資料的時候,就可以讀了)
    •   而網路卡能夠知道 fd 是否有時間發生,並通知作業系統,但使用者程式不知道
  • I/O 多路複用就是解決這一個問題,讓執行緒快速得知 fd 是否有事件發生(是否可以讀,是否可以寫)
    •   一個執行緒能併發的服務多個 I/O 事件,這就是 I/O 多路複用的含義

總結:如何理解 I/O 多路複用

  • 如果不使用 I/O 多路複用,在併發處理多個客戶端的 I/O 事件的的場景下,服務端需要透過建立子程序或者執行緒的方式,給每一個連線的 I/O 事件分配一個執行緒來處理,隨著客戶端越來越多,服務端需要建立更多的執行緒,系統的開銷太大,效率太低
  • 我們需要一種機制,讓一個執行緒能併發的服務多個 I/O 事件,這就是 I/O 多路複用的含義
  • 所以作業系統設立了多種 I/O 多路複用的機制來解決這個問題,執行緒可以透過 select、poll、epoll 這類 I/O 多路複用系統呼叫介面從核心中透過網路卡獲取有事件發生的 socket 集合,然後就可以透過遍歷這個集合,對每一個 I/O 事件進行處理,這樣就實現了一個執行緒併發的處理多個 I/O 事件,大大提高了效率

這就是為什麼我們需要 I/O 多路複用的技術

相關文章