偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

迄今為止把同步/異步/阻塞/非阻塞/BIO/NIO/AIO講的這么清楚的好文章

系統(tǒng) Linux
網(wǎng)上有很多講同步/異步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都沒(méi)有達(dá)到我的心里預(yù)期,于是自己寫(xiě)一篇出來(lái)。

 [[264259]]

網(wǎng)上有很多講同步/異步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都沒(méi)有達(dá)到我的心里預(yù)期,于是自己寫(xiě)一篇出來(lái)。

常規(guī)的誤區(qū)

假設(shè)有一個(gè)展示用戶(hù)詳情的需求,分兩步,先調(diào)用一個(gè)HTTP接口拿到詳情數(shù)據(jù),然后使用適合的視圖展示詳情數(shù)據(jù)。

如果網(wǎng)速很慢,代碼發(fā)起一個(gè)HTTP請(qǐng)求后,就卡住不動(dòng)了,直到十幾秒后才拿到HTTP響應(yīng),然后繼續(xù)往下執(zhí)行。

這個(gè)時(shí)候你問(wèn)別人,剛剛代碼發(fā)起的這個(gè)請(qǐng)求是不是一個(gè)同步請(qǐng)求,對(duì)方一定回答是。這是對(duì)的,它確實(shí)是。

但你要問(wèn)它為什么是呢?對(duì)方一定是這樣回答的,“因?yàn)榘l(fā)起請(qǐng)求后,代碼就卡住不動(dòng)了,直到拿到響應(yīng)后才可以繼續(xù)往下執(zhí)行”。

我相信很多人也都是這樣認(rèn)為的,其實(shí)這是不對(duì)的,是把因果關(guān)系搞反了:

不是因?yàn)榇a卡住不動(dòng)了才叫同步請(qǐng)求,而是因?yàn)樗峭秸?qǐng)求所以代碼才卡住不動(dòng)了。

至于為什么能卡住不動(dòng),這是由操作系統(tǒng)和CPU決定的:

因?yàn)閮?nèi)核空間里的對(duì)應(yīng)函數(shù)會(huì)卡住不動(dòng),造成用戶(hù)空間發(fā)起的系統(tǒng)調(diào)用卡住不動(dòng),繼而使程序里的用戶(hù)代碼卡住不動(dòng)了。

因此卡住不動(dòng)了只是同步請(qǐng)求的一個(gè)副作用,并不能用它來(lái)定義同步請(qǐng)求,那該如何定義呢?

同步和異步

所謂同步,指的是協(xié)同步調(diào)。既然叫協(xié)同,所以至少要有2個(gè)以上的事物存在。協(xié)同的結(jié)果就是:

多個(gè)事物不能同時(shí)進(jìn)行,必須一個(gè)一個(gè)的來(lái),上一個(gè)事物結(jié)束后,下一個(gè)事物才開(kāi)始。

那當(dāng)一個(gè)事物正在進(jìn)行時(shí),其它事物都在干嘛呢?

嚴(yán)格來(lái)講這個(gè)并沒(méi)有要求,但一般都是處于一種“等待”的狀態(tài),因?yàn)橥ǔ:竺媸挛锏恼_M(jìn)行都需要依賴(lài)前面事物的結(jié)果或前面事物正在使用的資源。

因此,可以認(rèn)為,同步更希望關(guān)注的是從宏觀整體來(lái)看,多個(gè)事物是一種逐個(gè)逐個(gè)的串行化關(guān)系,絕對(duì)不會(huì)出現(xiàn)交叉的情況。

所以,自然也不太會(huì)去關(guān)注某個(gè)瞬間某個(gè)具體事物是處于一個(gè)什么狀態(tài)。

把這個(gè)理論應(yīng)用的出神入化的非“排隊(duì)”莫屬。凡是在資源少需求多的場(chǎng)景下都會(huì)用到排隊(duì)。

比如排隊(duì)買(mǎi)火車(chē)票這件事:

其實(shí)售票大廳更在意的是旅客一個(gè)一個(gè)的到窗口去買(mǎi)票,因?yàn)橐淮沃荒苜u(mài)一張票。

即使大家一窩蜂的都圍上去,還是一次只能賣(mài)一張票,何必呢?擠在一起又不安全。

只是有些人素質(zhì)太差,非要往上擠,售票大廳迫不得已,采用排隊(duì)這種形式來(lái)達(dá)到自己的目的,即一個(gè)一個(gè)的買(mǎi)票。

至于每個(gè)旅客排隊(duì)時(shí)的狀態(tài),是看手機(jī)呀還是說(shuō)話呀,根本不用去在意。

除了這種由于資源導(dǎo)致的同步外,還存在一種由于邏輯上的先后順序?qū)е碌耐健?/p>

比如,先更新代碼,然后再編譯,接著再打包。這些操作由于后一步要使用上一步的結(jié)果,所以只能按照這種順序一個(gè)一個(gè)的執(zhí)行。

關(guān)于同步還需知道兩個(gè)小的點(diǎn):

一是范圍,并不需要在全局范圍內(nèi)都去同步,只需要在某些關(guān)鍵的點(diǎn)執(zhí)行同步即可。

比如食堂只有一個(gè)賣(mài)飯窗口,肯定是同步的,一個(gè)人買(mǎi)完,下一個(gè)人再買(mǎi)。但吃飯的時(shí)候也是一個(gè)人吃完,下一個(gè)人才開(kāi)始吃嗎?當(dāng)然不是啦。

二是粒度,并不是只有大粒度的事物才有同步,小粒度的事物也有同步。

只不過(guò)小粒度的事物同步通常是天然支持的,而大粒度的事物同步往往需要手工處理。

比如兩個(gè)線程的同步就需要手工處理,但一個(gè)線程里的兩個(gè)語(yǔ)句天然就是同步的。

所謂異步,就是步調(diào)各異。既然是各異,那就是都不相同。所以結(jié)果就是:

多個(gè)事物可以你進(jìn)行你的、我進(jìn)行我的,誰(shuí)都不用管誰(shuí),所有的事物都在同時(shí)進(jìn)行中。

一言以蔽之,同步就是多個(gè)事物不能同時(shí)開(kāi)工,異步就是多個(gè)事物可以同時(shí)開(kāi)工。

注:一定要去體會(huì)“多個(gè)事物”,多個(gè)線程是多個(gè)事物,多個(gè)方法是多個(gè)事物,多個(gè)語(yǔ)句是多個(gè)事物,多個(gè)CPU指令是多個(gè)事物。等等等等。

阻塞和非阻塞

所謂阻塞,指的是阻礙堵塞。它的本意可以理解為由于遇到了障礙而造成的動(dòng)彈不得。

所謂非阻塞,自然是和阻塞相對(duì),可以理解為由于沒(méi)有遇到障礙而繼續(xù)暢通無(wú)阻。

對(duì)這兩個(gè)詞詮釋就是,當(dāng)今中國(guó)一大交通難題,堵車(chē):

汽車(chē)可以正常通行時(shí),就是非阻塞。一旦堵上了,全部趴窩,一動(dòng)不動(dòng),就是阻塞。

因此阻塞關(guān)注的是不能動(dòng),非阻塞關(guān)注的是可以動(dòng)。

不能動(dòng)的結(jié)果就是只能等待,可以動(dòng)的結(jié)果就是繼續(xù)前行。

因此和阻塞搭配的詞一定是等待,和非阻塞搭配的詞一定是進(jìn)行。

回到程序里,阻塞同樣意味著停下來(lái)等待,非阻塞表明可以繼續(xù)向下執(zhí)行。

阻塞和等待

等待只是阻塞的一個(gè)副作用而已,表明隨著時(shí)間的流逝,沒(méi)有任何有意義的事物發(fā)生或進(jìn)行。

阻塞的真正含義是你關(guān)心的事物由于某些原因無(wú)法繼續(xù)進(jìn)行,因此讓你等待。但沒(méi)必要干等,你可以做一些其它無(wú)關(guān)的事物,因?yàn)檫@并不影響你對(duì)相關(guān)事物的等待。

在堵車(chē)時(shí),你可以干等。也可以玩手機(jī)、和別人聊天,或者打牌、甚至先去吃飯都行。因?yàn)檫@些事物并不影響你對(duì)堵車(chē)的等待。不過(guò)你的車(chē)必須呆在原地。

在計(jì)算機(jī)里,是沒(méi)有人這么靈活的,一般在阻塞時(shí),選在干等,因?yàn)檫@最容易實(shí)現(xiàn),只需要掛起線程,讓出CPU即可。在條件滿(mǎn)足時(shí),會(huì)重新調(diào)度該線程。

兩兩組合

所謂同步/異步,關(guān)注的是能不能同時(shí)開(kāi)工。

所謂阻塞/非阻塞,關(guān)注的是能不能動(dòng)。

通過(guò)推理進(jìn)行組合:

同步阻塞,不能同時(shí)開(kāi)工,也不能動(dòng)。只有一條小道,一次只能過(guò)一輛車(chē),可悲的是堵上了。

同步非阻塞,不能同時(shí)開(kāi)工,但可以動(dòng)。只有一條小道,一次只能過(guò)一輛車(chē),幸運(yùn)的是可以正常通行。

異步阻塞,可以同時(shí)開(kāi)工,但不可以動(dòng)。有多條路,每條路都可以跑車(chē),可氣的是全都堵上了。

異步非阻塞,可以工時(shí)開(kāi)工,也可以動(dòng)。有多條路,每條路都可以跑車(chē),很爽的是全都可以正常通行。

是不是很容易理解啊。其實(shí)它們的關(guān)注點(diǎn)是不同的,只要搞明白了這點(diǎn),組合起來(lái)也不是事兒。

回到程序里,把它們和線程關(guān)聯(lián)起來(lái):

同步阻塞,相當(dāng)于一個(gè)線程在等待。

同步非阻塞,相當(dāng)于一個(gè)線程在正常運(yùn)行。

異步阻塞,相當(dāng)于多個(gè)線程都在等待。

異步非阻塞,相當(dāng)于多個(gè)線程都在正常運(yùn)行。

I/O

IO指的就是讀入/寫(xiě)出數(shù)據(jù)的過(guò)程,和等待讀入/寫(xiě)出數(shù)據(jù)的過(guò)程。一旦拿到數(shù)據(jù)后就變成了數(shù)據(jù)操作了,就不是IO了。

拿網(wǎng)絡(luò)IO來(lái)說(shuō),等待的過(guò)程就是數(shù)據(jù)從網(wǎng)絡(luò)到網(wǎng)卡再到內(nèi)核空間。讀寫(xiě)的過(guò)程就是內(nèi)核空間和用戶(hù)空間的相互拷貝。

所以IO就包括兩個(gè)過(guò)程,一個(gè)是等待數(shù)據(jù)的過(guò)程,一個(gè)是讀寫(xiě)(拷貝)數(shù)據(jù)的過(guò)程。而且還要明白,一定不能包括操作數(shù)據(jù)的過(guò)程。

阻塞IO和非阻塞IO

應(yīng)用程序都是運(yùn)行在用戶(hù)空間的,所以它們能操作的數(shù)據(jù)也都在用戶(hù)空間。按照這樣子來(lái)理解,只要數(shù)據(jù)沒(méi)有到達(dá)用戶(hù)空間,用戶(hù)線程就操作不了。

如果此時(shí)用戶(hù)線程已經(jīng)參與,那它一定會(huì)被阻塞在IO上。這就是常說(shuō)的阻塞IO。用戶(hù)線程被阻塞在等待數(shù)據(jù)上或拷貝數(shù)據(jù)上。

非阻塞IO就是用戶(hù)線程不參與以上兩個(gè)過(guò)程,即數(shù)據(jù)已經(jīng)拷貝到用戶(hù)空間后,才去通知用戶(hù)線程,一上來(lái)就可以直接操作數(shù)據(jù)了。

用戶(hù)線程沒(méi)有因?yàn)镮O的事情出現(xiàn)阻塞,這就是常說(shuō)的非阻塞IO。

同步IO和同步阻塞IO

按照上文中對(duì)同步的理解,同步IO是指發(fā)起IO請(qǐng)求后,必須拿到IO的數(shù)據(jù)才可以繼續(xù)執(zhí)行。

按照程序的表現(xiàn)形式又分為兩種:

在等待數(shù)據(jù)的過(guò)程中,和拷貝數(shù)據(jù)的過(guò)程中,線程都在阻塞,這就是同步阻塞IO。

在等待數(shù)據(jù)的過(guò)程中,線程采用死循環(huán)式輪詢(xún),在拷貝數(shù)據(jù)的過(guò)程中,線程在阻塞,這其實(shí)還是同步阻塞IO。

網(wǎng)上很多文章把第二種歸為同步非阻塞IO,這肯定是錯(cuò)誤的,它一定是阻塞IO,因?yàn)榭截悢?shù)據(jù)的過(guò)程,線程是阻塞的。

嚴(yán)格來(lái)講,在IO的概念上,同步和非阻塞是不可能搭配的,因?yàn)樗鼈兪且粚?duì)相悖的概念。

同步IO意味著必須拿到IO的數(shù)據(jù),才可以繼續(xù)執(zhí)行。因?yàn)楹罄m(xù)操作依賴(lài)IO數(shù)據(jù),所以它必須是阻塞的。

非阻塞IO意味著發(fā)起IO請(qǐng)求后,可以繼續(xù)往下執(zhí)行。說(shuō)明后續(xù)執(zhí)行不依賴(lài)于IO數(shù)據(jù),所以它肯定不是同步的。

因此,在IO上,同步和非阻塞是互斥的,所以不存在同步非阻塞IO。但同步非阻塞是存在的,那不叫IO,叫操作數(shù)據(jù)了。

所以,同步IO一定是阻塞IO,同步IO也就是同步阻塞IO。

異步IO和異步阻塞/非阻塞IO

按照上文中對(duì)異步的理解,異步IO是指發(fā)起IO請(qǐng)求后,不用拿到IO的數(shù)據(jù)就可以繼續(xù)執(zhí)行。

用戶(hù)線程的繼續(xù)執(zhí)行,和操作系統(tǒng)準(zhǔn)備IO數(shù)據(jù)的過(guò)程是同時(shí)進(jìn)行的,因此才叫做異步IO。

按照IO數(shù)據(jù)的兩個(gè)過(guò)程,又可以分為兩種:

在等待數(shù)據(jù)的過(guò)程中,用戶(hù)線程繼續(xù)執(zhí)行,在拷貝數(shù)據(jù)的過(guò)程中,線程在阻塞,這就是異步阻塞IO。

在等待數(shù)據(jù)的過(guò)程中,和拷貝數(shù)據(jù)的過(guò)程中,用戶(hù)線程都在繼續(xù)執(zhí)行,這就是異步非阻塞IO。

一種情況是,用戶(hù)線程沒(méi)有參與數(shù)據(jù)等待的過(guò)程,所以它是異步的。但用戶(hù)線程參與了數(shù)據(jù)拷貝的過(guò)程,所以它又是阻塞的。合起來(lái)就是異步阻塞IO。

第二種情況是,用戶(hù)線程既沒(méi)有參與等待過(guò)程也沒(méi)有參與拷貝過(guò)程,所以它是異步的。當(dāng)它接到通知時(shí),數(shù)據(jù)已經(jīng)準(zhǔn)備好了,它沒(méi)有因?yàn)镮O數(shù)據(jù)而阻塞過(guò),所以它又是非阻塞的。合起來(lái)就是異步非阻塞IO。

 

責(zé)任編輯:武曉燕 來(lái)源: 編程新說(shuō)
相關(guān)推薦

2021-03-04 08:34:55

同步阻塞非阻塞

2020-02-06 14:22:31

理解入門(mén)文章

2012-02-22 21:15:41

unixIO阻塞

2019-07-23 11:01:57

Python同步異步

2015-10-29 13:04:47

.NET技術(shù)棧

2012-10-10 10:00:27

同步異步開(kāi)發(fā)Java

2018-03-28 08:52:53

阻塞非阻塞I

2015-07-03 10:12:04

編程同步非阻塞

2021-12-01 07:26:13

IO模型異步

2024-09-23 17:15:28

Python并發(fā)并行

2011-12-07 10:53:38

Path應(yīng)用設(shè)計(jì)移動(dòng)應(yīng)用

2024-03-26 07:59:32

IO模型多路復(fù)用

2009-11-20 09:20:11

Windows 7系統(tǒng)評(píng)價(jià)

2024-04-29 07:01:00

數(shù)據(jù)保護(hù)法數(shù)據(jù)泄露隱私法律

2022-05-13 23:35:19

Java編程語(yǔ)言開(kāi)發(fā)

2021-06-04 18:14:15

阻塞非阻塞tcp

2019-10-18 08:22:43

BIONIOAIO

2010-05-26 11:37:43

高密度光纜UHD美國(guó)康普

2011-01-20 09:44:24

蘋(píng)果iPhoneiPad

2015-07-23 14:28:04

.NET技術(shù)大系
點(diǎn)贊
收藏

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