多種IO模型

本篇文章是作為學(xué)習(xí)NIO的前置文章的闯袒,在學(xué)習(xí)NIO之前必須得了解一下IO模型旬牲。

對(duì)于一次IO訪問(以read舉例),數(shù)據(jù)會(huì)先被拷貝到操作系統(tǒng)內(nèi)核的緩沖區(qū)中搁吓,然后才會(huì)從操作系統(tǒng)內(nèi)核的緩沖區(qū)拷貝到應(yīng)用程序的地址空間原茅。所以說,當(dāng)一個(gè)read操作發(fā)生時(shí)堕仔,它會(huì)經(jīng)歷兩個(gè)階段:

  • 第一階段:等待數(shù)據(jù)準(zhǔn)備 (Waiting for the data to be ready)擂橘。
  • 第二階段:將數(shù)據(jù)從內(nèi)核拷貝到進(jìn)程中 (Copying the data from the kernel to the process)。

對(duì)于socket流而言:
第一步:通常涉及等待網(wǎng)絡(luò)上的數(shù)據(jù)分組到達(dá)摩骨,然后被復(fù)制到內(nèi)核的某個(gè)緩沖區(qū)通贞。
第二步:把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)。

網(wǎng)絡(luò)應(yīng)用需要處理的無非就是兩大類問題恼五,網(wǎng)絡(luò)IO昌罩,數(shù)據(jù)計(jì)算。相對(duì)于后者灾馒,網(wǎng)絡(luò)IO的延遲茎用,給應(yīng)用帶來的性能瓶頸大于后者。網(wǎng)絡(luò)IO的模型大致有如下幾種:

  • 阻塞IO(bloking IO)
  • 非阻塞IO(non-blocking IO)
  • 多路復(fù)用IO(multiplexing IO)
  • 信號(hào)驅(qū)動(dòng)式IO(signal-driven IO)
  • 異步IO(asynchronous IO)

阻塞I/O模型

默認(rèn)情況下睬罗,socket都是阻塞類型的轨功,一個(gè)典型的讀流程應(yīng)該是這樣的:


阻塞IO模型.png
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

當(dāng)用戶進(jìn)程調(diào)用了recvfrom這個(gè)系統(tǒng)調(diào)用,kernel就開始了IO的第一個(gè)階段:準(zhǔn)備數(shù)據(jù)(對(duì)于網(wǎng)絡(luò)IO來說容达,很多時(shí)候數(shù)據(jù)在一開始還沒有到達(dá)古涧。比如,還沒有收到一個(gè)完整的UDP包花盐。這個(gè)時(shí)候kernel就要等待足夠的數(shù)據(jù)到來)羡滑。這個(gè)過程需要等待,也就是說數(shù)據(jù)被拷貝到操作系統(tǒng)內(nèi)核的緩沖區(qū)中是需要一個(gè)過程的算芯。而在用戶進(jìn)程這邊柒昏,整個(gè)進(jìn)程會(huì)被阻塞(當(dāng)然,是進(jìn)程自己選擇的阻塞)也祠。當(dāng)kernel一直等到數(shù)據(jù)準(zhǔn)備好了昙楚,它就會(huì)將數(shù)據(jù)從kernel中拷貝到用戶內(nèi)存,然后kernel返回結(jié)果诈嘿,用戶進(jìn)程才解除block的狀態(tài)堪旧,重新運(yùn)行起來削葱。所以,blocking IO的特點(diǎn)就是在IO執(zhí)行的兩個(gè)階段都被block了淳梦。

非阻塞I/O模型

非阻塞IO模型.png

當(dāng)用戶進(jìn)程發(fā)出read操作時(shí)析砸,如果kernel中的數(shù)據(jù)還沒有準(zhǔn)備好,那么它并不會(huì)block用戶進(jìn)程爆袍,而是立刻返回一個(gè)error首繁。從用戶進(jìn)程角度講 ,它發(fā)起一個(gè)read操作后陨囊,并不需要等待弦疮,而是馬上就得到了一個(gè)結(jié)果。用戶進(jìn)程判斷結(jié)果是一個(gè)error時(shí)蜘醋,它就知道數(shù)據(jù)還沒有準(zhǔn)備好胁塞,于是它可以再次發(fā)送read操作。一旦kernel中的數(shù)據(jù)準(zhǔn)備好了压语,并且又再次收到了用戶進(jìn)程的system call啸罢,那么它馬上就將數(shù)據(jù)拷貝到了用戶內(nèi)存,然后返回胎食。所以扰才,nonblocking IO的特點(diǎn)是用戶進(jìn)程需要不斷的主動(dòng)詢問kernel數(shù)據(jù)好了沒有。

I/O多路復(fù)用

最常用的的I/O事件通知機(jī)制就是I/O復(fù)用厕怜。Linux 環(huán)境中使用select/poll/epoll_wait 實(shí)現(xiàn)I/O復(fù)用衩匣,I/O復(fù)用接口本身是阻塞的,在應(yīng)用程序中通過I/O復(fù)用接口向內(nèi)核注冊(cè)fd所關(guān)注的事件酣倾,當(dāng)關(guān)注事件觸發(fā)時(shí)舵揭,通過I/O復(fù)用接口的返回值通知到應(yīng)用程序谤专。I/O復(fù)用接口可以同時(shí)監(jiān)聽多個(gè)I/O事件以提高事件處理效率躁锡。
使用 select 或者 poll 等待數(shù)據(jù),并且可以等待多個(gè)套接字中的任何一個(gè)變?yōu)榭勺x置侍,這一過程會(huì)被阻塞映之,當(dāng)某一個(gè)套接字可讀時(shí)返回。之后再使用 recvfrom 把數(shù)據(jù)從內(nèi)核復(fù)制到進(jìn)程中蜡坊。
它可以讓單個(gè)進(jìn)程具有處理多個(gè) I/O 事件的能力杠输。又被稱為 Event Driven I/O,即事件驅(qū)動(dòng) I/O秕衙。

IO復(fù)用模型.png
IO多路復(fù)用的理解.png
NIO如何實(shí)現(xiàn)多路復(fù)用.png
SIGIO 信號(hào)驅(qū)動(dòng) I/O

應(yīng)用進(jìn)程使用 sigaction 系統(tǒng)調(diào)用蠢甲,內(nèi)核立即返回,應(yīng)用進(jìn)程可以繼續(xù)執(zhí)行据忘,也就是說等待數(shù)據(jù)階段應(yīng)用進(jìn)程是非阻塞的鹦牛。內(nèi)核在數(shù)據(jù)到達(dá)時(shí)向應(yīng)用進(jìn)程發(fā)送 SIGIO 信號(hào)搞糕,應(yīng)用進(jìn)程收到之后在信號(hào)處理程序中調(diào)用 recvfrom 將數(shù)據(jù)從內(nèi)核復(fù)制到應(yīng)用進(jìn)程中。
相比于非阻塞式 I/O 的輪詢方式曼追,信號(hào)驅(qū)動(dòng) I/O 的 CPU 利用率更高窍仰。


信號(hào)驅(qū)動(dòng)IO.png
AIO 異步IO(asynchronous IO AIO)

進(jìn)行 aio_read 系統(tǒng)調(diào)用會(huì)立即返回,應(yīng)用進(jìn)程繼續(xù)執(zhí)行礼殊,不會(huì)被阻塞驹吮,內(nèi)核會(huì)在所有操作完成之后向應(yīng)用進(jìn)程發(fā)送信號(hào)。異步 I/O 與信號(hào)驅(qū)動(dòng) I/O 的區(qū)別在于晶伦,異步 I/O 的信號(hào)是通知應(yīng)用進(jìn)程 I/O 完成碟狞,而信號(hào)驅(qū)動(dòng) I/O 的信號(hào)是通知應(yīng)用進(jìn)程可以開始 I/O。


異步IO.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末婚陪,一起剝皮案震驚了整個(gè)濱河市篷就,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌近忙,老刑警劉巖竭业,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異及舍,居然都是意外死亡未辆,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門锯玛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咐柜,“玉大人,你說我怎么就攤上這事攘残∽居眩” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵歼郭,是天一觀的道長(zhǎng)遗契。 經(jīng)常有香客問我,道長(zhǎng)病曾,這世上最難降的妖魔是什么牍蜂? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮泰涂,結(jié)果婚禮上鲫竞,老公的妹妹穿的比我還像新娘。我一直安慰自己逼蒙,他們只是感情好从绘,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般僵井。 火紅的嫁衣襯著肌膚如雪赁还。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天驹沿,我揣著相機(jī)與錄音艘策,去河邊找鬼。 笑死渊季,一個(gè)胖子當(dāng)著我的面吹牛朋蔫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播却汉,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼驯妄,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了合砂?” 一聲冷哼從身側(cè)響起青扔,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翩伪,沒想到半個(gè)月后微猖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缘屹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年凛剥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片轻姿。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡犁珠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出互亮,到底是詐尸還是另有隱情犁享,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布豹休,位于F島的核電站炊昆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏慕爬。R本人自食惡果不足惜窑眯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望医窿。 院中可真熱鬧,春花似錦炊林、人聲如沸姥卢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽独榴。三九已至僧叉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棺榔,已是汗流浹背瓶堕。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工晌块, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畔塔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓监婶,卻偏偏與公主長(zhǎng)得像忘晤,于是被迫代替她去往敵國(guó)和親宛蚓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容