面試經典問題 --- IO多路複用


前言

之前其實有專門去了解過關於 I / O 多路複用的知識,但是前兩天在面試UCloud的時候,有問到這方面的問題,發現還是有所欠缺,再次梳理一下。

PS:這是圖解算法講的IO多路複用,我覺得講的很好,我的整理也是基於這篇文章的,推薦大家去看看


一、I / O 多路複用講是什麼問題 ?

首先需要了解什麼是IO多路複用? IO 是什麼 ? 多路複用又是什麼?

1.1 到底什麼是 I / O ?

我們常說的IO,指的是文件的輸入和輸出,但是在操作系統層面是如何定義IO的呢?到底什麼樣的過程可以叫做是一次IO呢?
拿一次磁盤文件讀取爲例,我們要讀取的文件是存儲在磁盤上的,我們的目的是把它讀取到內存中。可以把這個步驟簡化成把數據從硬件(硬盤)中讀取到用戶空間中。

1.2 什麼是多路複用 ?

單個線程,通過記錄跟蹤每個I/O流(socket)的狀態,來同時管理多個I/O流 。

二、有哪些IO模型 ? 又有什麼區別 ?

2.1 有哪些IO模型 ?

在Java中,主要有三種IO模型,分別是阻塞IO(BIO)、非阻塞IO(NIO)和 異步IO(AIO)。

在Linux(UNIX)操作系統中,共有五種IO模型,分別是:阻塞IO模型、非阻塞IO模型、IO複用模型、信號驅動IO模型以及異步IO模型。

2.2 各種IO模型的區別

阻塞IO模型

阻塞 I/O 是最簡單的 I/O 模型,一般表現爲進程或線程等待某個條件,如果條件不滿足,則一直等下去。條件滿足,則進行下一步操作。

應用進程通過系統調用 recvfrom 接收數據,但由於內核還未準備好數據報,應用進程就會阻塞住,直到內核準備好數據報,recvfrom 完成數據報復制工作,應用進程才能結束阻塞狀態。

非阻塞IO模型

Linux操作系統中的非阻塞的IO模型。應用進程與內核交互,目的未達到之前,不再一味的等着,而是直接返回。然後通過輪詢的方式,不停的去問內核數據準備有沒有準備好。如果某一次輪詢發現數據已經準備好了,那就把數據拷貝到用戶空間中。

在這裏插入圖片描述

應用進程通過 recvfrom 調用不停的去和內核交互,直到內核準備好數據。如果沒有準備好,內核會返回error,應用進程在得到error後,過一段時間再發送recvfrom請求。在兩次發送請求的時間段,進程可以先做別的事情。

信號驅動IO模型

信號驅動IO。應用進程在讀取文件時通知內核,如果某個 socket 的某個事件發生時,請向我發一個信號。在收到信號後,信號對應的處理函數會進行後續處理。

在這裏插入圖片描述

應用進程預先向內核註冊一個信號處理函數,然後用戶進程返回,並且不阻塞,當內核數據準備就緒時會發送一個信號給進程,用戶進程便在信號處理函數中開始把數據拷貝的用戶空間中。

IO複用模型

IO複用模型。多個進程的IO可以註冊到同一個管道上,這個管道會統一和內核進行交互。當管道中的某一個請求需要的數據準備好之後,進程再把對應的數據拷貝到用戶空間中。

在這裏插入圖片描述
IO多路轉接是多了一個select函數,多個進程的IO可以註冊到同一個select上,當用戶進程調用該selectselect會監聽所有註冊好的IO,如果所有被監聽的IO需要的數據都沒有準備好時,select調用進程會阻塞。當任意一個IO所需的數據準備好之後,select調用就會返回,然後進程在通過recvfrom來進行數據拷貝。

這裏的IO複用模型,並沒有向內核註冊信號處理函數,所以,他並不是非阻塞的。進程在發出select後,要等到select監聽的所有IO操作中至少有一個需要的數據準備好,纔會有返回,並且也需要再次發送請求去進行文件的拷貝。

小結: 上述四個模型都是同步模型。

爲什麼以上四種都是同步的 ?

我們說阻塞IO模型、非阻塞IO模型、IO複用模型和信號驅動IO模型都是同步的IO模型。原因是因爲,無論以上那種模型,真正的數據拷貝過程,都是同步進行的。

信號驅動難道不是異步的麼? 信號驅動,內核是在數據準備好之後通知進程,然後進程再通過recvfrom操作進行數據拷貝。我們可以認爲數據準備階段是異步的,但是,數據拷貝操作是同步的。所以,整個IO過程也不能認爲是異步的。

異步IO模型

異步IO模型。應用進程把IO請求傳給內核後,完全由內核去操作文件拷貝。內核完成相關操作後,會發信號告訴應用進程本次IO已經完成。

在這裏插入圖片描述

用戶進程發起aio_read操作之後,給內核傳遞描述符、緩衝區指針、緩衝區大小等,告訴內核當整個操作完成時,如何通知進程,然後就立刻去做其他事情了。當內核收到aio_read後,會立刻返回,然後內核開始等待數據準備,數據準備好以後,直接把數據拷貝到用戶控件,然後再通知進程本次IO已經完成。

總結

5種IO模型對比

在這裏插入圖片描述

相關文章
相關標籤/搜索
每日一句
    每一个你不满意的现在,都有一个你没有努力的曾经。