異步IO

摘自廖雪峰教程

在IO編程一節(jié)中吻商,我們已經(jīng)知道掏颊,CPU的速度遠(yuǎn)遠(yuǎn)快于磁盤、網(wǎng)絡(luò)等IO艾帐。在一個線程中乌叶,CPU執(zhí)行代碼的速度極快,然而柒爸,一旦遇到IO操作准浴,如讀寫文件、發(fā)送網(wǎng)絡(luò)數(shù)據(jù)時捎稚,就需要等待IO操作完成乐横,才能繼續(xù)進(jìn)行下一步操作。這種情況稱為同步IO今野。

在IO操作的過程中葡公,當(dāng)前線程被掛起,而其他需要CPU執(zhí)行的代碼就無法被當(dāng)前線程執(zhí)行了腥泥。

因?yàn)橐粋€IO操作就阻塞了當(dāng)前線程匾南,導(dǎo)致其他代碼無法執(zhí)行啃匿,所以我們必須使用多線程或者多進(jìn)程來并發(fā)執(zhí)行代碼蛔外,為多個用戶服務(wù)。每個用戶都會分配一個線程溯乒,如果遇到IO導(dǎo)致線程被掛起夹厌,其他用戶的線程不受影響。

多線程和多進(jìn)程的模型雖然解決了并發(fā)問題裆悄,但是系統(tǒng)不能無上限地增加線程。由于系統(tǒng)切換線程的開銷也很大,所以事镣,一旦線程數(shù)量過多驳规,CPU的時間就花在線程切換上了,真正運(yùn)行代碼的時間就少了艾君,結(jié)果導(dǎo)致性能嚴(yán)重下降采够。

由于我們要解決的問題是CPU高速執(zhí)行能力和IO設(shè)備的龜速嚴(yán)重不匹配,多線程和多進(jìn)程只是解決這一問題的一種方法冰垄。

另一種解決IO問題的方法是異步IO蹬癌。當(dāng)代碼需要執(zhí)行一個耗時的IO操作時,它只發(fā)出IO指令,并不等待IO結(jié)果逝薪,然后就去執(zhí)行其他代碼了隅要。一段時間后,當(dāng)IO返回結(jié)果時董济,再通知CPU進(jìn)行處理步清。

可以想象如果按普通順序?qū)懗龅拇a實(shí)際上是沒法完成異步IO的:

“do_some_code()

f = open('/path/to/file', 'r')

r = f.read() #<==線程停在此處等待IO操作結(jié)果

do_some_code(r)#IO操作

完成后線程才能繼續(xù)執(zhí)行:do_some_code(r)

所以虏肾,同步IO模型的代碼是無法實(shí)現(xiàn)異步IO模型的崖瞭。

異步IO模型需要一個消息循環(huán)藻雌,在消息循環(huán)中驯杜,主線程不斷地重復(fù)“讀取消息-處理消息”這一過程:

loop = get_event_loop()

whileTrue:? ?

? ? ? ? ?event = loop.get_event()? ?

? ? ? ? ?process_event(event)

消息模型其實(shí)早在應(yīng)用在桌面應(yīng)用程序中了。一個GUI程序的主線程就負(fù)責(zé)不停地讀取消息并處理消息顽频。所有的鍵盤、鼠標(biāo)等消息都被發(fā)送到GUI程序的消息隊(duì)列中,然后由GUI程序的主線程處理。

由于GUI線程處理鍵盤仗岖、鼠標(biāo)等消息的速度非常快檩电,所以用戶感覺不到延遲奄侠。某些時候烹卒,GUI線程在一個消息處理的過程中遇到問題導(dǎo)致一次消息處理時間過長牡整,此時谣辞,用戶會感覺到整個GUI程序停止響應(yīng)了迫皱,敲鍵盤凹炸、點(diǎn)鼠標(biāo)都沒有反應(yīng)舱痘。這種情況說明在消息模型中,處理一個消息必須非常迅速离赫,否則芭逝,主線程將無法及時處理消息隊(duì)列中的其他消息,導(dǎo)致程序看上去停止響應(yīng)渊胸。

消息模型是如何解決同步IO必須等待IO操作這一問題的呢旬盯?當(dāng)遇到IO操作時,代碼只負(fù)責(zé)發(fā)出IO請求翎猛,不等待IO結(jié)果胖翰,然后直接結(jié)束本輪消息處理,進(jìn)入下一輪消息處理過程切厘。當(dāng)IO操作完成后萨咳,將收到一條“IO完成”的消息,處理該消息時就可以直接獲取IO操作結(jié)果疫稿。

在“發(fā)出IO請求”到收到“IO完成”的這段時間里某弦,同步IO模型下,主線程只能掛起而克,但異步IO模型下靶壮,主線程并沒有休息,而是在消息循環(huán)中繼續(xù)處理其他消息员萍。這樣腾降,在異步IO模型下,一個線程就可以同時處理多個IO請求碎绎,并且沒有切換線程的操作螃壤。對于大多數(shù)IO密集型的應(yīng)用程序,使用異步IO將大大提升系統(tǒng)的多任務(wù)處理能力筋帖。

舉例:

UNIX有5種I/O模型,阻塞會發(fā)生在兩個階段上:

1.阻塞式I/O? ? 等待數(shù)據(jù)時阻塞? 數(shù)據(jù)從內(nèi)核復(fù)制到用戶空間時阻塞

2.非阻塞式I/O 等待數(shù)據(jù)不阻塞,但是輪詢會占用cpu資源 數(shù)據(jù)從內(nèi)核復(fù)制到用戶空間時阻塞

3.I/O復(fù)用? 考慮到輪詢占用cpu資源的問題,阻塞在選擇器上,減輕處理器負(fù)擔(dān)? 將數(shù)據(jù)從內(nèi)核復(fù)制到用戶空間時阻塞

4.信號驅(qū)動式I/O 等待數(shù)據(jù)不阻塞,數(shù)據(jù)準(zhǔn)備好時通知接收數(shù)據(jù),將數(shù)據(jù)從內(nèi)核復(fù)制到用戶空間時阻塞

以上四種或多或少均有阻塞現(xiàn)象存在,它們都是同步I/O模型

5.異步I/O 等待數(shù)據(jù)時不阻塞 將數(shù)據(jù)從內(nèi)核復(fù)制到用戶空間時也不阻塞. 數(shù)據(jù)到了用戶空間以后才發(fā)信號,就像你在網(wǎng)上下了訂單,快遞員拿著你的快件站在你家門口才通知你開門簽收的樣子.

而在網(wǎng)上下了訂單,貨物到了離你家最近的自提點(diǎn),商城通知你去自提點(diǎn)取提貨.你專門抽出時間去提貨.這是4.信號驅(qū)動式I/O.因?yàn)樵趤砘刈蕴狳c(diǎn)的路上你其實(shí)是阻塞的.


例子2:

老張愛喝茶奸晴,廢話不說,煮開水日麸。

出場人物:老張寄啼,水壺兩把(普通水壺,簡稱水壺代箭;會響的水壺墩划,簡稱響水壺)。

1 老張把水壺放到火上嗡综,立等水開乙帮。(同步阻塞)

老張覺得自己有點(diǎn)傻

2 老張把水壺放到火上,去客廳看電視极景,時不時去廚房看看水開沒有察净。(同步非阻塞)

老張還是覺得自己有點(diǎn)傻驾茴,于是變高端了,買了把會響笛的那種水壺氢卡。水開之后沟涨,能大聲發(fā)出嘀~~~~的噪音。

3 老張把響水壺放到火上异吻,立等水開裹赴。(異步阻塞)

老張覺得這樣傻等意義不大

4 老張把響水壺放到火上,去客廳看電視诀浪,水壺響之前不再去看它了棋返,響了再去拿壺。(異步非阻塞)

老張覺得自己聰明了雷猪。

所謂同步異步睛竣,只是對于水壺而言。

普通水壺求摇,同步射沟;響水壺,異步与境。

雖然都能干活验夯,但響水壺可以在自己完工之后,提示老張水開了摔刁。這是普通水壺所不能及的挥转。

同步只能讓調(diào)用者去輪詢自己(情況2中),造成老張效率的低下共屈。

所謂阻塞非阻塞绑谣,僅僅對于老張而言。

立等的老張拗引,阻塞借宵;看電視的老張,非阻塞矾削。

情況1和情況3中老張就是阻塞的壤玫,媳婦喊他都不知道。雖然3中響水壺是異步的怔软,可對于立等的老張沒有太大的意義垦细。所以一般異步是配合非阻塞使用的,這樣才能發(fā)揮異步的效用挡逼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市腻豌,隨后出現(xiàn)的幾起案子家坎,更是在濱河造成了極大的恐慌嘱能,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虱疏,死亡現(xiàn)場離奇詭異惹骂,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)做瞪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門对粪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人装蓬,你說我怎么就攤上這事著拭。” “怎么了牍帚?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵儡遮,是天一觀的道長。 經(jīng)常有香客問我暗赶,道長鄙币,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任蹂随,我火速辦了婚禮十嘿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岳锁。我一直安慰自己详幽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布浸锨。 她就那樣靜靜地躺著唇聘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪柱搜。 梳的紋絲不亂的頭發(fā)上迟郎,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音聪蘸,去河邊找鬼宪肖。 笑死,一個胖子當(dāng)著我的面吹牛健爬,可吹牛的內(nèi)容都是我干的控乾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼娜遵,長吁一口氣:“原來是場噩夢啊……” “哼蜕衡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起设拟,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤慨仿,失蹤者是張志新(化名)和其女友劉穎久脯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镰吆,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帘撰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了万皿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摧找。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牢硅,靈堂內(nèi)的尸體忽然破棺而出蹬耘,到底是詐尸還是另有隱情,我是刑警寧澤唤衫,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布婆赠,位于F島的核電站,受9級特大地震影響佳励,放射性物質(zhì)發(fā)生泄漏休里。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一赃承、第九天 我趴在偏房一處隱蔽的房頂上張望妙黍。 院中可真熱鬧,春花似錦瞧剖、人聲如沸拭嫁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽做粤。三九已至,卻和暖如春捉撮,著一層夾襖步出監(jiān)牢的瞬間怕品,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工巾遭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肉康,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓灼舍,卻偏偏與公主長得像吼和,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子骑素,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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