自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

送分來了,華為一面,介紹下五種 IO 模型

存儲 存儲架構
異步 IO 的兩個階段,用戶進程都是非阻塞的,用戶進程將整個 IO 操作都交由內核完成,內核完成后會發(fā)送通知。在此期間,用戶進程不需要去檢查 IO 操作的狀態(tài),也不需要主動的去拷貝數據。

所謂 I/O,就是 Input/Output,輸入/輸出,在操作系統(tǒng)中,輸入輸出操作其實并不簡單

工作在用戶態(tài)的應用程序想要讀取磁盤中的具體文件內容,就需要經過 System Call(系統(tǒng)調用)陷入內核態(tài)

因此,在操作系統(tǒng)中,輸入輸出操作通常都會包括以下兩個階段:

  1. 準備數據:內核緩沖區(qū)準備數據,等待其準備好
  2. 數據拷貝:從內核緩沖區(qū)向用戶緩沖區(qū)復制數據

以網絡通信即 Socket 上的輸入操作為例,對應的第一階就是等待數據從網絡中到達網卡(對于網絡 I/O 來說,很多時候數據在一開始還沒有到達。比如,還沒有收到一個完整的 TCP 包。這個時候內核就要等待足夠的數據到來),然后從網卡中將數據拷貝到內核緩沖區(qū),這樣,數據就準備就完成了;第二階段就是把數據從內核緩沖區(qū)復制到用戶緩沖區(qū)。

圖片

操作系統(tǒng)系統(tǒng)如何去管理輸入和輸出,從而獲取輸入和輸出的數據?這就是 I/O 模型。

Linux 中有以下五種 I/O 模型:

  • Blocking I/O:阻塞 I/O
  • Non-Blocking I/O:非阻塞 I/O
  • I/O Multiplexing:I/O 多路復用
  • Signal Blocking I/O:信號驅動 I/O
  • Asynchronous I/O:異步 I/O

Blocking I/O

在 Linux 中,默認情況下所有的 Socket 都是 Blocking,它符合人們最常見的思考邏輯。

上面我們介紹了輸入輸出操作通常都會包括兩個階段,并不是憑空想想,而是對應具體的 I/O 系統(tǒng)調用的,以網絡通信為例,Blocking I/O 就對應阻塞的系統(tǒng)調用 recvfrom

第一階段,準備數據:當用戶進程通過系統(tǒng)調用 recvfrom 進行數據讀取,操作系統(tǒng)就開始了 I/O 的第一個階段-準備數據。這個過程需要等待,也就是說數據被拷貝到操作系統(tǒng)內核的緩沖區(qū)中是需要一個過程的。而在用戶進程這邊,整個進程會被阻塞住

解釋下 阻塞 的概念:源自操作系統(tǒng)對進程/線程狀態(tài)的描述概念,其定義為:操作系統(tǒng)把進程/線程從“運行(running)狀態(tài)” 掛起為 “阻塞(blocked)狀態(tài)”(又稱“等待(waiting)狀態(tài)”)。當進程/線程處于阻塞狀態(tài),則意味著其處于暫停運行狀態(tài),暫時不會被 CPU 調度執(zhí)行

第二階段,數據拷貝:當內核一直等到數據準備好了,它就會將數據從內核空間中拷貝到用戶空間,然后系統(tǒng)調用 recvfrom 返回結果,用戶進程才解除阻塞的狀態(tài),重新運行起來

圖片

在上述步驟中,用戶進程調用 recvfrom,該系統(tǒng)調用直到數據準備好且被復制到用戶緩沖區(qū)中才返回。

從調用 recvfrom 開始,到它返回數據的整段時間,用戶進程都是被阻塞住的!這就是 Blocking I/O 的特點,可以簡單記憶為 “IO 執(zhí)行的兩個階段用戶進程都被阻塞住了”

recvfrom 成功返回后,用戶進程才開始繼續(xù)處理。

Non-Blocking I/O

參考《Unix 網絡編程:第一卷》,書中是這樣描述 Non-Blocking I/O 的:

"進程把一個套接字設置成非阻塞是在通知內核,當所請求的 I/O 操作非得把本進程投入睡眠才能完成時,不要把進程投入睡眠,而是返回一個錯誤"

意思就是,如果某個用戶進程進行系統(tǒng)調用 recvform 嘗試獲取數據,但這時候數據還沒準備好:

  • 如果操作系統(tǒng)把這個進程掛起,那就是 Blocking I/O
  • 如果操作系統(tǒng)選擇立即給用戶進程返回錯誤信息,那就是 Non-Blocking I/O

如下圖所示:

圖片

非阻塞的 recvform? 系統(tǒng)調用之后,如果數據還沒準備好,應用進程不會被阻塞住,recvfrom? 立即返回一個 EWOULDBLOCK? 錯誤。用戶進程在收到 recvfrom 調用的返回信息之后,可以干點別的事情,然后再發(fā)起 recvform 系統(tǒng)調用。

重復上面的過程,不斷地進行 recvform 系統(tǒng)調用。這個過程通常被稱之為**輪詢 (polling)**。輪詢檢查內核數據,直到數據準備好,再拷貝數據到用戶進程,進行數據處理。

需要注意的是,當 recvfrom 系統(tǒng)調用進行拷貝數據的時候,用戶進程同樣是被阻塞住的。

因此,Non-Blocking I/O 的特點就是用戶進程需要不斷的主動詢問內核數據準備好了沒有,可以簡單記憶為 “IO 執(zhí)行的第一階段用戶進程非阻塞,第二階段用戶進程阻塞”

I/O Multiplexing

由于 Non-Blocking I/O 需要不斷主動輪詢,輪詢會消耗大量的 CPU 時間,而后臺可能有多個任務在同時進行,人們就想到了循環(huán)查詢多個任務的完成狀態(tài),只要有任何一個任務完成,就去處理它。這就是 I/O Multiplexing。

I/O Multiplexing 引入了新的系統(tǒng)調用 select/poll/epoll(也成為多路復用器),這幾個系統(tǒng)調用也是重點,不過本文就不過多闡述了。

具體來說,I/O Multiplexing 就是將多個應用進程的 Socket 注冊到一個多路復用器(select/poll/epoll)上,然后使用一個進程來監(jiān)聽該多路復用器,多路復用器會不斷的輪詢所有注冊進來的 Socket,只要有一個 Socket 的數據準備好,就會返回該 Socket。再由應用進程發(fā)起真正的 IO 系統(tǒng)調用(也就是 recvfrom,和 Blocking I/O 一樣),來完成數據讀取。

簡單來說,I/O Multiplexing 就是同時阻塞了多個應用進程,而且可以同時對多個 Socket 進行檢測,直到有數據可讀或可寫時,才真正開始 I/O 操作。

圖片

比較上圖和 Blocking I/O,你會發(fā)現 I/O Multiplexing 的 I/O 操作和 Blocking I/O 似乎差不多,事實上,IO 多路復用還更差一些,因為這里需要使用兩個系統(tǒng)調用 (select? 和 recvfrom?),而 Blocking IO 只需要一個系統(tǒng)調用 (recvfrom)。

但是,IO 多路復用的優(yōu)勢并不是對單個連接能處理得更快,而是只需要一個進程就可以同時處理多個 I/O,能同時處理更多的連接。

Signal Blocking I/O

Signal Blocking I/O 就是當用戶進程發(fā)起 I/O 操作的時候,首先通過系統(tǒng)調用 sigaction? 向內核注冊一個信號處理函數,這個系統(tǒng)調用會立即返回不會阻塞用戶進程;當內核數據準備好了就會發(fā)送一個 SIGIO 信號給用戶進程,這樣用戶進程就知道內核數據準備好了,可以開始執(zhí)行 I/O 系統(tǒng)調用了。

圖片

和 Non-Blocking I/O 一樣,信號驅動 IO 的用戶進程在 I/O 的第一階段準備數據是非阻塞的,在第二階段數據拷貝是阻塞的

不過信號驅動 IO 基于回調機制,其實現和開發(fā)應用難度大,因此在實際中并不常用。

Asynchronous I/O

異步 I/O,先來解釋下什么是異步?

POSIX 的定義如下:

  • 同步 I/O 操作(synchronous I/O operation):導致請求進程阻塞,直到 I/O 操作完成
  • 異步 I/O 操作(asynchronous I/O operation):不導致請求進程阻塞

根據這個定義,我們可以做一個分類了,那就是上述四種 I/O 都是同步 I/O!因為它們無一例外都會在第二階段阻塞住用戶進程直到 I/O 操作完成。

這就是為什么你會看見有人把 “阻塞 I/O” 稱之為 “同步 阻塞 I/O”,把 “非阻塞 I/O” 稱之為 “同步 非阻塞 I/O” 了

而異步 IO 所謂的在整個 I/O 操作期間都不會阻塞用戶進程,其通常的工作機制是:

用戶進程告知內核啟動某個 I/O 操作,并讓內核在整個操作(包括將數據從內核復制到用戶緩沖區(qū))完成后通知用戶進程。

這與 Signal Blocking I/O 的本質區(qū)別就是:

  • Signal Blocking I/O 是在數據準備好了之后進行通知,告知應用進程可以啟動 I/O 操作進行拷貝數據了
  • Asynchronous I/O 是在整個 I/O 操作完成了之后進行通知,告知應用進程 I/O 操作已經完成了

下圖給出了一個異步調用的例子:

圖片

用戶進程進行異步系統(tǒng)調用 aio_read? 之后,無論內核數據是否準備好,都會直接返回給用戶進程,然后用戶進程可以去做別的事情。等到數據準備好了,內核直接拷貝數據給用戶進程(不需要用戶進程再主動發(fā)起 recvfrom 系統(tǒng)調用),拷貝完畢后內核才會給用戶進程發(fā)送通知,告訴用戶進程操作已經完成了。

所以,異步 IO 的兩個階段,用戶進程都是非阻塞的,用戶進程將整個 IO 操作都交由內核完成,內核完成后會發(fā)送通知。在此期間,用戶進程不需要去檢查 IO 操作的狀態(tài),也不需要主動的去拷貝數據。

五種 I/O 模型比較

本文理清了五種 I/O 模型,并區(qū)分了阻塞/非阻塞、同步和異步的概念

最后上張圖對比下,加深印象

? 圖片 ?

責任編輯:武曉燕 來源: 飛天小牛肉
相關推薦

2017-01-17 14:21:27

LinuxIO模型Unix

2025-03-07 00:11:00

JWTJSONSession

2022-05-11 22:15:51

云計算云平臺

2024-05-15 16:41:57

進程IO文件

2009-07-30 14:38:36

云計算

2020-09-19 17:46:20

React Hooks開發(fā)函數

2011-12-23 09:43:15

開源開放

2011-12-22 20:53:40

Android

2023-05-05 09:48:14

LinuxIO模型

2013-09-16 10:52:09

2025-04-24 10:05:51

2021-11-03 09:03:09

面試鏈接http

2023-05-16 18:06:24

聯想

2012-12-19 09:04:29

2022-05-10 08:11:15

MySQL技巧結構

2022-03-30 10:10:17

字節(jié)碼??臻g

2025-04-01 08:40:00

HTTPRPC開發(fā)

2022-08-13 12:07:14

URLHTTP加密

2023-09-04 00:00:07

百度長連接網絡

2022-05-11 15:57:16

優(yōu)化SQL
點贊
收藏

51CTO技術棧公眾號