Java NIO(一)-I/O模型: 阻塞砾嫉、非阻塞幼苛、I/O復(fù)用、同步焕刮、異步

目的##

為后期學(xué)習(xí) Netty框架打好理論基礎(chǔ)舶沿,并且在分布式RPC 服務(wù)中對客戶端與服務(wù)端之間服務(wù)的調(diào)用,底層數(shù)據(jù)通訊可以使用Netty 進(jìn)行封裝配并。

記錄結(jié)構(gòu)##


今天記錄I/O模型中的阻塞邑闲、非阻塞、I/O復(fù)用梧油、同步苫耸、異步。

混沌的概念##

對于上述四種概念婶溯,常常使我陷入混沌,我經(jīng)常這樣想同步不就是阻塞的么?異步不就是非阻塞的么迄委?
我也會去看下別人寫的博客以驗(yàn)證我的想法是正確的褐筛,事實(shí)上,大多博客也這樣舉例子:同步類似于你叫某人吃飯叙身,某人不應(yīng)答你渔扎,你就一直等著他,這期間你什么事情都不能做信轿,也就是說你在等待某人去吃飯這個時刻內(nèi)一直都是阻塞的晃痴。
針對于上述的舉例,我一直深信不疑财忽,一句話倘核,沒毛病

但直到我看到UNIX 網(wǎng)絡(luò)編程之后即彪,才發(fā)現(xiàn)理解有偏差紧唱,起碼我之前的理解是將I/O操作中的概念結(jié)合起來記憶。即:同步==阻塞 異步==非阻塞隶校。

但其實(shí)漏益,以上的記憶有點(diǎn)以偏概全,或者說根本沒有清晰的認(rèn)識深胳。

話不多說绰疤,開始記錄。

1. 明確I/O考察的對象和流程##


1.1 參考Unix網(wǎng)絡(luò)編程舞终,一個輸入操作通常包括兩個不同的階段:

  • 等待數(shù)據(jù)準(zhǔn)備好轻庆;
  • 從內(nèi)核向進(jìn)程復(fù)制數(shù)據(jù)。

1.2 對于一個套接字的輸入操作:

  • 通常涉及等待數(shù)據(jù)從網(wǎng)絡(luò)到達(dá)权埠,當(dāng)所等待分組到達(dá)時榨了,被復(fù)制到內(nèi)核的某個緩沖區(qū);
  • 把數(shù)據(jù)從內(nèi)核緩沖區(qū)復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)。

注意: 理解上述兩個不同階段對于后續(xù)理解I/O模型尤其是非阻塞I/O與同步I/O關(guān)系十分必要攘蔽。

2. I/O模型##


2.1 阻塞式I/O模型
阻塞式I/O是最流行的I/O龙屉,也是所有套接字默認(rèn)的I/O。Java BIO中對socket 網(wǎng)絡(luò)數(shù)據(jù)通信的
封裝 就采用的是這種方式满俗。當(dāng)然效率也是低下的转捕。

阻塞式I/O是最流行的I/O,也是所有套接字默認(rèn)的I/O唆垃。

阻塞式I/O.png

(注:所有圖片來源 Unix網(wǎng)絡(luò)編程卷1五芝,第三版)

如圖所示,進(jìn)程調(diào)用recvfrom系統(tǒng)調(diào)用辕万,直到網(wǎng)絡(luò)數(shù)據(jù)報到達(dá)且被復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)中或發(fā)生錯誤才返回枢步。

注意:也就是說沉删,進(jìn)程從調(diào)用recvfrom開始到返回的整個時段都是阻塞的(上述1.1兩個階段都是阻塞),recvfrom成功返回后醉途,應(yīng)用進(jìn)程才開始處理數(shù)據(jù)報矾瑰。

上述的注意讀三遍

2.2 非阻塞I/O模型
直接上圖:

非阻塞式I/O

如圖所示,不同于阻塞式I/O隘擎,非阻塞I/O在第一階段數(shù)據(jù)沒有準(zhǔn)備好的時候殴穴,不阻塞,而是直接返回一個錯誤(EWOULDBLOCK)货葬。

所以一般采用輪詢(polling)的方式采幌,應(yīng)用進(jìn)程持續(xù)輪詢內(nèi)核,查看數(shù)據(jù)是否準(zhǔn)備好震桶。當(dāng)數(shù)據(jù)準(zhǔn)備好時休傍,被復(fù)制到應(yīng)用進(jìn)程緩沖區(qū)(第二階段)。

注意:值得注意的一點(diǎn)是尼夺,當(dāng)?shù)谝浑A段數(shù)據(jù)準(zhǔn)備完成后尊残,進(jìn)入第二階段,內(nèi)核向內(nèi)存的復(fù)制淤堵。這一階段仍然是阻塞的寝衫,這對于后續(xù)理解非阻塞與同步的關(guān)系十分重要。

上述注意項(xiàng)讀三遍拐邪。

2.3 I/O多路復(fù)用模型
I/O復(fù)用最常見的就是select和epoll慰毅,其阻塞發(fā)生在上述兩個系統(tǒng)調(diào)用之一,而不是真正的I/O系統(tǒng)調(diào)用上扎阶。 Java NIO 對TCP 網(wǎng)絡(luò)通信的封裝內(nèi)部采用的就是這種原理汹胃。

I/O復(fù)用模型.png

當(dāng)用戶進(jìn)程調(diào)用了select,那么整個進(jìn)程會被阻塞與select东臀。內(nèi)核會“監(jiān)視”所有select負(fù)責(zé)的套接字着饥,當(dāng)任何一個套接字中的數(shù)據(jù)準(zhǔn)備好了,select就會返回惰赋。(進(jìn)程阻塞)

這時候進(jìn)入第二階段宰掉,完成內(nèi)核向內(nèi)存的數(shù)據(jù)復(fù)制。(進(jìn)程阻塞)

注意:I/O復(fù)用的優(yōu)勢在于同時等待多個描述符就緒赁濒,單就一個描述符可言轨奄,其沒有優(yōu)勢,反而還會因?yàn)槎嘁淮蝧elect系統(tǒng)調(diào)用存在劣勢拒炎。

上述注意項(xiàng)讀三遍挪拟。

2.4 異步I/O模型
異步I/O的工作機(jī)制是告知內(nèi)核啟動某個操作,并讓內(nèi)核在整個操作(包括第二階段數(shù)據(jù)從內(nèi)核向內(nèi)存的復(fù)制)完成后告知我們击你。

如下圖所示:

異步I/O 模型.png

注意:異步I/O要通過調(diào)用特殊API實(shí)現(xiàn)(如POSIX的aio_read)玉组,可以看出谎柄,其在兩個階段都是沒有對于用戶進(jìn)程的阻塞的,依靠信號通知進(jìn)程整個過程完成惯雳。

上述注意讀三遍

2.5 同步谷誓、異步與阻塞、非阻塞吨凑、I/O復(fù)用的關(guān)系
在了解了阻塞式I/O、非阻塞式I/O户辱、I/O多路復(fù)用鸵钝、異步I/O后我們看下這幾個模式的I/O模型與同步異步模型有什么關(guān)系。
注意:重頭戲庐镐,接下來就是徹底領(lǐng)悟這幾個概念之間關(guān)系恩商,讓你不再混沌,請保持接受狀態(tài)必逆,保持信心看下去怠堪。

首先先來再明確一下同步、異步I/O之間的區(qū)別名眉。
書中所述粟矿,POSIX把兩種術(shù)語定義如下:
同步I/O:導(dǎo)致請求進(jìn)程阻塞,直到I/O操作完成损拢;(兩個階段(等待網(wǎng)絡(luò)數(shù)據(jù)到達(dá)內(nèi)核空間緩存區(qū)域陌粹,以及將內(nèi)核空間緩存區(qū)域中的數(shù)據(jù)復(fù)制到用戶進(jìn)程緩存中)中只要有一個階段阻塞,那整個I/O操作就就是同步)
異步I/O:不導(dǎo)致請求進(jìn)程阻塞福压。 (兩個階段都不阻塞掏秩,那么就是異步I/O)

注意:所以說,阻塞式I/O荆姆, 非阻塞I/O蒙幻, I/O復(fù)用由于都導(dǎo)致了請求進(jìn)程阻塞,所以均屬于同步I/O胆筒。
(值得注意的是非阻塞I/O邮破,正如之前提示要注意的,其在第二階段內(nèi)核向內(nèi)存復(fù)制數(shù)據(jù)是會導(dǎo)致用戶進(jìn)程的阻塞腐泻,所以也屬于同步I/O

上述注意讀三遍

3. 總結(jié)
如下圖所示:(暫時忽略信號驅(qū)動I/O)

每種I/O的特點(diǎn)和調(diào)用流程.png

可以看出阻塞式决乎、非阻塞式、與I/O復(fù)用派桩,其不同之處在于第一階段构诚,第二階段的處理方式相同(均阻塞與recvfrom調(diào)用),這也是剛才說到的將他們歸于同步I/O的原因铆惑。

注意:異步I/O不存在請求進(jìn)程阻塞的情況范嘱。同時注意前三種I/O模型在第一階段的處理方式(阻塞送膳,返回+輪詢,阻塞于select等)丑蛤,區(qū)分這三種I/O模型叠聋。

上述注意讀三遍

關(guān)于公眾號

精進(jìn)!
道友們受裹,你們好碌补。早前個人就有開設(shè)公眾號的念想,今年10月終于開搞了棉饶。
我的個人的 訂閱號--T客來了厦章;
平時自己會總結(jié)一些后端開發(fā)相關(guān)的技術(shù);
最近也迷上了音視頻開發(fā)相關(guān)技術(shù)照藻;

技術(shù)分享包括:

  • 1.FFmpeg 工程實(shí)戰(zhàn)袜啃、
  • 2.數(shù)據(jù)庫 MySQL原理與實(shí)戰(zhàn)、
  • 3.Redis中間件幸缕、
  • 4.Nginx群发、Java并發(fā)編程、
  • 5.Go語言方面的技術(shù)知識與實(shí)操;


    T客來了

點(diǎn)擊微信圖標(biāo)发乔,掃碼就可以添加哦~
完熟妓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市栏尚,隨后出現(xiàn)的幾起案子滑蚯,更是在濱河造成了極大的恐慌,老刑警劉巖抵栈,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件告材,死亡現(xiàn)場離奇詭異,居然都是意外死亡古劲,警方通過查閱死者的電腦和手機(jī)斥赋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來产艾,“玉大人疤剑,你說我怎么就攤上這事∶票ぃ” “怎么了隘膘?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長杠览。 經(jīng)常有香客問我弯菊,道長,這世上最難降的妖魔是什么踱阿? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任管钳,我火速辦了婚禮钦铁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘才漆。我一直安慰自己牛曹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布醇滥。 她就那樣靜靜地躺著黎比,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鸳玩。 梳的紋絲不亂的頭發(fā)上焰手,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音怀喉,去河邊找鬼。 笑死船响,一個胖子當(dāng)著我的面吹牛躬拢,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播见间,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼聊闯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了米诉?” 一聲冷哼從身側(cè)響起菱蔬,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎史侣,沒想到半個月后拴泌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惊橱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年蚪腐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片税朴。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡回季,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出正林,到底是詐尸還是另有隱情泡一,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布觅廓,位于F島的核電站鼻忠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杈绸。R本人自食惡果不足惜粥烁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一贤笆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧讨阻,春花似錦芥永、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奇瘦,卻和暖如春棘催,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耳标。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工醇坝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人次坡。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓呼猪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親砸琅。 傳聞我的和親對象是個殘疾皇子宋距,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355

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