成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

送分來(lái)了,華為一面,介紹下五種 IO 模型

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

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

工作在用戶態(tài)的應(yīng)用程序想要讀取磁盤(pán)中的具體文件內(nèi)容,就需要經(jīng)過(guò) System Call(系統(tǒng)調(diào)用)陷入內(nèi)核態(tài)

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

  1. 準(zhǔn)備數(shù)據(jù):內(nèi)核緩沖區(qū)準(zhǔn)備數(shù)據(jù),等待其準(zhǔn)備好
  2. 數(shù)據(jù)拷貝:從內(nèi)核緩沖區(qū)向用戶緩沖區(qū)復(fù)制數(shù)據(jù)

以網(wǎng)絡(luò)通信即 Socket 上的輸入操作為例,對(duì)應(yīng)的第一階就是等待數(shù)據(jù)從網(wǎng)絡(luò)中到達(dá)網(wǎng)卡(對(duì)于網(wǎng)絡(luò) I/O 來(lái)說(shuō),很多時(shí)候數(shù)據(jù)在一開(kāi)始還沒(méi)有到達(dá)。比如,還沒(méi)有收到一個(gè)完整的 TCP 包。這個(gè)時(shí)候內(nèi)核就要等待足夠的數(shù)據(jù)到來(lái)),然后從網(wǎng)卡中將數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),這樣,數(shù)據(jù)就準(zhǔn)備就完成了;第二階段就是把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到用戶緩沖區(qū)。

圖片

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

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

  • Blocking I/O:阻塞 I/O
  • Non-Blocking I/O:非阻塞 I/O
  • I/O Multiplexing:I/O 多路復(fù)用
  • Signal Blocking I/O:信號(hào)驅(qū)動(dòng) I/O
  • Asynchronous I/O:異步 I/O

Blocking I/O

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

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

第一階段,準(zhǔn)備數(shù)據(jù):當(dāng)用戶進(jìn)程通過(guò)系統(tǒng)調(diào)用 recvfrom 進(jìn)行數(shù)據(jù)讀取,操作系統(tǒng)就開(kāi)始了 I/O 的第一個(gè)階段-準(zhǔn)備數(shù)據(jù)。這個(gè)過(guò)程需要等待,也就是說(shuō)數(shù)據(jù)被拷貝到操作系統(tǒng)內(nèi)核的緩沖區(qū)中是需要一個(gè)過(guò)程的。而在用戶進(jìn)程這邊,整個(gè)進(jìn)程會(huì)被阻塞住

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

第二階段,數(shù)據(jù)拷貝:當(dāng)內(nèi)核一直等到數(shù)據(jù)準(zhǔn)備好了,它就會(huì)將數(shù)據(jù)從內(nèi)核空間中拷貝到用戶空間,然后系統(tǒng)調(diào)用 recvfrom 返回結(jié)果,用戶進(jìn)程才解除阻塞的狀態(tài),重新運(yùn)行起來(lái)

圖片

在上述步驟中,用戶進(jìn)程調(diào)用 recvfrom,該系統(tǒng)調(diào)用直到數(shù)據(jù)準(zhǔn)備好且被復(fù)制到用戶緩沖區(qū)中才返回。

從調(diào)用 recvfrom 開(kāi)始,到它返回?cái)?shù)據(jù)的整段時(shí)間,用戶進(jìn)程都是被阻塞住的!這就是 Blocking I/O 的特點(diǎn),可以簡(jiǎn)單記憶為 “IO 執(zhí)行的兩個(gè)階段用戶進(jìn)程都被阻塞住了”

recvfrom 成功返回后,用戶進(jìn)程才開(kāi)始繼續(xù)處理。

Non-Blocking I/O

參考《Unix 網(wǎng)絡(luò)編程:第一卷》,書(shū)中是這樣描述 Non-Blocking I/O 的:

"進(jìn)程把一個(gè)套接字設(shè)置成非阻塞是在通知內(nèi)核,當(dāng)所請(qǐng)求的 I/O 操作非得把本進(jìn)程投入睡眠才能完成時(shí),不要把進(jìn)程投入睡眠,而是返回一個(gè)錯(cuò)誤"

意思就是,如果某個(gè)用戶進(jìn)程進(jìn)行系統(tǒng)調(diào)用 recvform 嘗試獲取數(shù)據(jù),但這時(shí)候數(shù)據(jù)還沒(méi)準(zhǔn)備好:

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

如下圖所示:

圖片

非阻塞的 recvform? 系統(tǒng)調(diào)用之后,如果數(shù)據(jù)還沒(méi)準(zhǔn)備好,應(yīng)用進(jìn)程不會(huì)被阻塞住,recvfrom? 立即返回一個(gè) EWOULDBLOCK? 錯(cuò)誤。用戶進(jìn)程在收到 recvfrom 調(diào)用的返回信息之后,可以干點(diǎn)別的事情,然后再發(fā)起 recvform 系統(tǒng)調(diào)用。

重復(fù)上面的過(guò)程,不斷地進(jìn)行 recvform 系統(tǒng)調(diào)用。這個(gè)過(guò)程通常被稱之為**輪詢 (polling)**。輪詢檢查內(nèi)核數(shù)據(jù),直到數(shù)據(jù)準(zhǔn)備好,再拷貝數(shù)據(jù)到用戶進(jìn)程,進(jìn)行數(shù)據(jù)處理。

需要注意的是,當(dāng) recvfrom 系統(tǒng)調(diào)用進(jìn)行拷貝數(shù)據(jù)的時(shí)候,用戶進(jìn)程同樣是被阻塞住的。

因此,Non-Blocking I/O 的特點(diǎn)就是用戶進(jìn)程需要不斷的主動(dòng)詢問(wèn)內(nèi)核數(shù)據(jù)準(zhǔn)備好了沒(méi)有,可以簡(jiǎn)單記憶為 “IO 執(zhí)行的第一階段用戶進(jìn)程非阻塞,第二階段用戶進(jìn)程阻塞”

I/O Multiplexing

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

I/O Multiplexing 引入了新的系統(tǒng)調(diào)用 select/poll/epoll(也成為多路復(fù)用器),這幾個(gè)系統(tǒng)調(diào)用也是重點(diǎn),不過(guò)本文就不過(guò)多闡述了。

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

簡(jiǎn)單來(lái)說(shuō),I/O Multiplexing 就是同時(shí)阻塞了多個(gè)應(yīng)用進(jìn)程,而且可以同時(shí)對(duì)多個(gè) Socket 進(jìn)行檢測(cè),直到有數(shù)據(jù)可讀或可寫(xiě)時(shí),才真正開(kāi)始 I/O 操作。

圖片

比較上圖和 Blocking I/O,你會(huì)發(fā)現(xiàn) I/O Multiplexing 的 I/O 操作和 Blocking I/O 似乎差不多,事實(shí)上,IO 多路復(fù)用還更差一些,因?yàn)檫@里需要使用兩個(gè)系統(tǒng)調(diào)用 (select? 和 recvfrom?),而 Blocking IO 只需要一個(gè)系統(tǒng)調(diào)用 (recvfrom)。

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

Signal Blocking I/O

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

圖片

和 Non-Blocking I/O 一樣,信號(hào)驅(qū)動(dòng) IO 的用戶進(jìn)程在 I/O 的第一階段準(zhǔn)備數(shù)據(jù)是非阻塞的,在第二階段數(shù)據(jù)拷貝是阻塞的

不過(guò)信號(hào)驅(qū)動(dòng) IO 基于回調(diào)機(jī)制,其實(shí)現(xiàn)和開(kāi)發(fā)應(yīng)用難度大,因此在實(shí)際中并不常用。

Asynchronous I/O

異步 I/O,先來(lái)解釋下什么是異步?

POSIX 的定義如下:

  • 同步 I/O 操作(synchronous I/O operation):導(dǎo)致請(qǐng)求進(jìn)程阻塞,直到 I/O 操作完成
  • 異步 I/O 操作(asynchronous I/O operation):不導(dǎo)致請(qǐng)求進(jìn)程阻塞

根據(jù)這個(gè)定義,我們可以做一個(gè)分類了,那就是上述四種 I/O 都是同步 I/O!因?yàn)樗鼈儫o(wú)一例外都會(huì)在第二階段阻塞住用戶進(jìn)程直到 I/O 操作完成。

這就是為什么你會(huì)看見(jiàn)有人把 “阻塞 I/O” 稱之為 “同步 阻塞 I/O”,把 “非阻塞 I/O” 稱之為 “同步 非阻塞 I/O” 了

而異步 IO 所謂的在整個(gè) I/O 操作期間都不會(huì)阻塞用戶進(jìn)程,其通常的工作機(jī)制是:

用戶進(jìn)程告知內(nèi)核啟動(dòng)某個(gè) I/O 操作,并讓內(nèi)核在整個(gè)操作(包括將數(shù)據(jù)從內(nèi)核復(fù)制到用戶緩沖區(qū))完成后通知用戶進(jìn)程。

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

  • Signal Blocking I/O 是在數(shù)據(jù)準(zhǔn)備好了之后進(jìn)行通知,告知應(yīng)用進(jìn)程可以啟動(dòng) I/O 操作進(jìn)行拷貝數(shù)據(jù)了
  • Asynchronous I/O 是在整個(gè) I/O 操作完成了之后進(jìn)行通知,告知應(yīng)用進(jìn)程 I/O 操作已經(jīng)完成了

下圖給出了一個(gè)異步調(diào)用的例子:

圖片

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

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

五種 I/O 模型比較

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

最后上張圖對(duì)比下,加深印象

? 圖片 ?

責(zé)任編輯:武曉燕 來(lái)源: 飛天小牛肉
相關(guān)推薦

2017-01-17 14:21:27

LinuxIO模型Unix

2025-03-07 00:11:00

JWTJSONSession

2022-05-11 22:15:51

云計(jì)算云平臺(tái)

2024-05-15 16:41:57

進(jìn)程IO文件

2009-07-30 14:38:36

云計(jì)算

2020-09-19 17:46:20

React Hooks開(kāi)發(fā)函數(shù)

2011-12-22 20:53:40

Android

2011-12-23 09:43:15

開(kāi)源開(kāi)放

2023-05-05 09:48:14

LinuxIO模型

2013-09-16 10:52:09

2025-04-24 10:05:51

2023-05-16 18:06:24

聯(lián)想

2021-11-03 09:03:09

面試鏈接http

2012-12-19 09:04:29

2022-05-10 08:11:15

MySQL技巧結(jié)構(gòu)

2022-08-13 12:07:14

URLHTTP加密

2022-03-30 10:10:17

字節(jié)碼棧空間

2025-04-01 08:40:00

HTTPRPC開(kāi)發(fā)

2022-05-11 15:57:16

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

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 男女视频在线观看网站 | 国产片一区二区三区 | 日本三级网站在线观看 | 欧美一区免费 | 精品九九| 欧美一区二区三区一在线观看 | 亚洲一区在线观看视频 | 国产成人一区二 | 亚洲国产成人在线观看 | 国产欧美在线一区 | 成人欧美一区二区三区视频xxx | 91成人免费电影 | 国产网站在线免费观看 | 91在线精品视频 | 91在线免费观看网站 | av一区二区三区四区 | 久草.com| 天天看夜夜 | 色欧美片视频在线观看 | 国产成人高清视频 | 超碰91在线 | 国产中文 | 国产不卡在线 | 亚洲精品永久免费 | 高清国产午夜精品久久久久久 | 一区二区三区欧美在线 | 日韩欧美在线免费 | 欧美日韩国产高清视频 | 操操操av | 人人干人人超 | 99视频在线免费观看 | 自拍偷拍中文字幕 | 欧洲一级毛片 | 日日干日日色 | 亚洲最大av| 欧美日韩精品一区二区三区四区 | 九九综合九九 | 国产视频久久 | 99精品欧美 | 黄色大片视频 | 极品国产视频 |