Unix網絡編程之5種IO模型

1. Unix/Linux操作系統簡述

Unix操作與Linux系統結構圖解 (引用計算機操作系統書籍)

在這裏插入圖片描述
在這裏插入圖片描述

概要說明

  • 用戶空間: 姑且將上述用戶級別或者是unix編程的應用程序的部分稱爲用戶空間,我們可以通過啓動進程來調用內核來完成從硬件設備讀取或寫入等操作
  • 系統內核: 是直接與計算機硬件打交道的應用程序級別,在計算機相關的書籍中也稱爲操作系統,可以通過操作系統級別提供的一些組件來幫助用戶進程與計算機硬件完成通信交互的操作,可以稱爲一箇中轉站

文件描述符(File descriptor)

在linux/unix系統中,文件進程存儲着一份文件描述表(數組存儲),數組存儲file結構指針類型,文件進程通過數組索引來完成文件的操作,這裏的數組索引也就是文件描述符,簡稱爲fd

至此,有了上述的認知之後,我們再來看下Unix的IO模型是如何進行網絡數據的傳輸

2. Unix之IO模型

首先,講述IO模型之前,需要先明確一個概念,比如我們現在需要從網絡讀取數據,那麼流程將是先從用戶進程中向系統內核發起讀取數據的操作,然後等待內核接收到網絡傳輸過來的數據報,有了數據報之後,根據上述操作系統的結構可知,我們需要將數據報通過系統內核複製到用戶空間上,這個時候用戶進程才能夠獲取到數據進行數據報的讀取,由此可知,一個輸入操作需要兩個階段:

  • 等待數據報可達,也就是系統內核必須要有接收到數據報
  • 有了數據報之後,需要將數據報從內核複製到用戶空間

另外

  • unix用recvfrom函數表示應用進程向系統內核發起讀取操作的系統調用

至此,網絡IO讀取操作有了上述的認知,接下來再看IO模式,注意默認情況下所有的套接字,即socket都是阻塞式的,以網絡讀取數據爲例展開,爲了簡化概念,將TCP的低套接字等信息隱藏不做說明,只說明IO模型,或者可以簡單理解爲UDP傳輸方式

阻塞式IO模型

  • 自應用進程發起recvfrom系統調用,在此期間一直處於被阻塞,因爲這個時候需要等待內核獲取數據報信息並將數據報復制到用戶空間中,除非被中斷異常返回,否則將一直處於阻塞狀態
  • 以下是時序圖展示阻塞式IO
    在這裏插入圖片描述

非阻塞式IO模型

  • 非阻塞式主要體現在用戶進程發起recvfrom系統調用的時候,這個時候系統內核還沒有接收到數據報,直接返回錯誤給用戶進程,告訴“當前還沒有數據報可達,晚點再來”
  • 用戶進程接收到信息,但是用戶進程不知道什麼時候數據報可達,於是就開始不斷輪詢(polling)向系統內核發起recvfrom的系統調用“詢問數據來了沒”,如果沒有則繼續返回錯誤
  • 用戶進程輪詢發起recvfrom系統調用直至數據報可達,這個時候需要等待系統內核複製數據報到用戶進程的緩衝區,複製完成之後將返回成功提示
  • 以下時序圖展示NIO的方式
    在這裏插入圖片描述

IO複用模型

  • IO複用模式是使用select或者poll函數向系統內核發起調用,阻塞在這兩個系統函數調用,而不是真正阻塞於實際的IO操作(recvfrom調用纔是實際阻塞IO操作的系統調用)
  • 阻塞於select函數的調用,等待數據報套接字變爲可讀狀態
  • 當select套接字返回可讀狀態的時候,就可以發起recvfrom調用把數據報復制到用戶空間的緩衝區
  • IO複用模式時序圖如下
    在這裏插入圖片描述

信號驅動式IO模型

  • 用戶進程可以使用信號方式,當系統內核描述符就緒時將會發送SIGNO給到用戶空間,這個時候再發起recvfrom的系統調用等待返回成功提示,流程如下
  • 先開啓套接字的信號IO驅動功能,並通過一個內置安裝信號處理函數的signaction系統調用,當發起調用之後將會直接返回
  • 其次,等待內核從網絡中接收數據報之後,向用戶空間發送當前數據可達的信號給到信號處理函數
  • 信號處理函數接收到信息就發起recvfrom系統調用等待內核複製數據報到用戶空間的緩衝區
  • 接收到複製完成的返回成功提示之後,應用進程就可以開始從網絡中讀取數據
  • 時序圖如下
    在這裏插入圖片描述

異步IO模型

  • 由POSIX規範定義,告知系統內核啓動某個操作,並讓內核在整個操作包括數據等待以及數據複製過程的完成之後通知用戶進程數據已經準備完成,可以進行讀取數據
  • 與上述的信號IO模型區分在於異步是通知我們何時IO操作完成,而信號IO是通知我們何時可以啓動一個IO操作
  • 時序圖如下
    在這裏插入圖片描述
  • 現代計算機服務器操作系統大部分都是基於linxu實現,爲處理高併發而採取NIO的模型,對於支持異步IO模型的系統持有不確定因素
3. 同步與異步和阻塞與非阻塞

同步與異步的定義

  • 同步:發起一個fn的調用,需要等待調用結果返回,該調用結果要麼是期望的結果要麼是異常拋出的結果,可以說是原子性操作(要麼成功要麼失敗返回)
  • 異步: 發起一個fn調用,無需等待結果就直接返回,只有當被調用者執行處理程序之後通過“喚醒”手段通知調用方獲取結果(喚醒的方式有回調,事件通知等)
  • 小結: 同步和異步關注的是程序之間的通信

阻塞與非阻塞的定義

  • 阻塞: 類比線程阻塞來說明,在併發多線程爭搶資源的競態條件下,如果有一個線程已持有鎖,那麼當前線程將無法獲取鎖而被掛起,處於等待狀態
  • 非阻塞: 一旦線程釋放鎖,其他線程將會進入就緒狀態,具備爭搶鎖的資格
  • 小結: 阻塞與非阻塞更關注是程序等待結果的狀態
  • 由此可知,同步異步與阻塞非阻塞之間不存在關聯,關注的目標是不一樣的

同步IO與異步IO(基於POSIX規範)

  • 同步IO: 表示應用進程發起真實的IO操作請求(recvfrom)導致進程一直處於等待狀態,這時候進程被阻塞,直到IO操作完成返回成功提示
  • 異步IO: 表示應用進程發起真實的IO操作請求(recvfrom)導致進程將直接返回一個錯誤信息,“相當於告訴進程還沒有處理好,好了會通知你”
  • 阻塞IO: 主要是體現發起IO操作請求通知內核並且內核接收到信號之後如果讓進程等待,那麼就是阻塞
  • 非阻塞IO: 發起IO操作請求的時候不論結果直接告訴進程“不用等待,晚點再來”,那就是非阻塞

IO模型對比

在這裏插入圖片描述

  • 根基上述的同步與異步IO定義並結合上述的模型可知,只有異步IO模型符合POSIX規範的異步IO,其他IO模型都存在recvfrom系統調用被內核阻塞,屬於同步IO操作

  • 由此可知,阻塞IO與非阻塞IO可總結如下:

  • 也就是說,要麼稱爲同步與異步IO,要麼稱爲上述5種模型的IO說法,注意上述的同步與異步的概念

  • 大部分操作系統都是基於同步IO的方式實現,對於支持異步IO模型的操作系統還不確定,在實際工作我們經常會說Blocking-IO(阻塞IO)和Non-Blocking-IO(非阻塞IO),極少稱同步IO與異步IO

  • 小結: 同步與異步針對通信機制,阻塞與非阻塞針對程序調用等待結果的狀態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章