深入理解異步I/O+epoll+協(xié)程

前言

同步和異步的概念描述的是用戶線程與內核的交互方式:同步是指用戶線程發(fā)起IO請求后需要等待或者輪詢內核IO操作完成后才能繼續(xù)執(zhí)行幕庐;而異步是指用戶線程發(fā)起IO請求后仍繼續(xù)執(zhí)行盼产,當內核IO操作完成后會通知用戶線程蝎土,或者調用用戶線程注冊的回調函數(shù)。
阻塞和非阻塞的概念描述的是用戶線程調用內核IO操作的方式:阻塞是指IO操作需要徹底完成后才返回到用戶空間润绵;而非阻塞是指IO操作被調用后立即返回給用戶一個狀態(tài)值,無需等到IO操作徹底完成。

異步I/O

在理解異步I/O之前葡盗,我們先要知道什么是同步I/O
阻塞同步I/O模型下,用戶線程向內核發(fā)起 recvfrom 系統(tǒng)調用啡浊,當數(shù)據沒有準備好的時候觅够,用戶線程阻塞。
此外還有一種非阻塞同步I/O巷嚣,此時用戶線程不阻塞于 recvfrom喘先,而是反復向系統(tǒng)查詢數(shù)據狀態(tài)。當數(shù)據準備好了廷粒,就對數(shù)據進行后續(xù)處理窘拯。

Paste_Image.png

而在異步I/O模式下,用戶線程在數(shù)據還沒有準備好的時候既不阻塞也不反復查詢坝茎,而是繼續(xù)干自己該干的事情涤姊。內核會開啟一個內核線程去讀取數(shù)據,等到數(shù)據準備好了嗤放,內核給用戶線程一個信號思喊,用戶線程中斷去執(zhí)行信號處理函數(shù)。

Paste_Image.png

node.js中的異步回調也是采用開線程的方式實現(xiàn)的

epoll

epoll/select 是一種I/O多路復用模型
用戶線程可以先通過 epoll 注冊多個I/O事件
然后用戶線程反復執(zhí)行調用 epoll/select 查詢是否有準備好的事件
如果有準備好的I/O事件則進行處理
關鍵點是一個用戶線程處理多個I/O事件

epoll/select 的區(qū)別在于
select 的底層原理是遍歷所有注冊的I/O事件次酌,找出準備好的的I/O事件恨课。
而 epoll 則是由內核主動通知哪些I/O事件需要處理,不需要用戶線程主動去反復查詢和措,因此大大提高了事件處理的效率庄呈。

Paste_Image.png

協(xié)程

協(xié)程是一種輕量級的線程
本質上協(xié)程就是用戶空間下的線程
如果把線程/進程當作虛擬“CPU”,協(xié)程即跑在這個“CPU”上的線程派阱。

協(xié)程的特點

  1. 占用的資源更少诬留。
  2. 所有的切換和調度都發(fā)生在用戶態(tài)。

不管是進程還是線程贫母,每次阻塞文兑、切換都需要陷入系統(tǒng)調用,先讓CPU跑操作系統(tǒng)的調度程序腺劣,然后再由調度程序決定該跑哪一個線程绿贞。而且由于搶占式調度執(zhí)行順序無法確定的特點,使用線程時需要非常小心地處理同步問題橘原,而協(xié)程完全不存在這個問題籍铁。
因為協(xié)程可以在用戶態(tài)顯示控制切換

例子
傳統(tǒng)的生產者-消費者模型是一個線程寫消息涡上,一個線程取消息,通過鎖機制控制隊列和等待拒名,但一不小心就可能死鎖吩愧。

如果改用協(xié)程,生產者生產消息后增显,直接通過yield跳轉到消費者開始執(zhí)行雁佳,待消費者執(zhí)行完畢后,切換回生產者繼續(xù)生產同云,效率極高:

import time

def consumer():
    r = ''
    while True:
        n = yield r
        if not n:
            return
        print('[CONSUMER] Consuming %s...' % n)
        time.sleep(1)
        r = '200 OK'

def produce(c):
    c.next()
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)
        print('[PRODUCER] Consumer return: %s' % r)
    c.close()

if __name__=='__main__':
    c = consumer()
    produce(c)

協(xié)程的優(yōu)點是可以用同步的處理方式實現(xiàn)異步回調的性能

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末糖权,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子炸站,更是在濱河造成了極大的恐慌星澳,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件武契,死亡現(xiàn)場離奇詭異募判,居然都是意外死亡,警方通過查閱死者的電腦和手機咒唆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門届垫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人全释,你說我怎么就攤上這事装处。” “怎么了浸船?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵妄迁,是天一觀的道長。 經常有香客問我李命,道長登淘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任封字,我火速辦了婚禮黔州,結果婚禮上,老公的妹妹穿的比我還像新娘阔籽。我一直安慰自己流妻,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布笆制。 她就那樣靜靜地躺著绅这,像睡著了一般。 火紅的嫁衣襯著肌膚如雪在辆。 梳的紋絲不亂的頭發(fā)上证薇,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天度苔,我揣著相機與錄音,去河邊找鬼棕叫。 笑死林螃,一個胖子當著我的面吹牛奕删,可吹牛的內容都是我干的俺泣。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼完残,長吁一口氣:“原來是場噩夢啊……” “哼伏钠!你這毒婦竟也來了?” 一聲冷哼從身側響起谨设,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤熟掂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后扎拣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體赴肚,經...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年二蓝,在試婚紗的時候發(fā)現(xiàn)自己被綠了誉券。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡刊愚,死狀恐怖踊跟,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情鸥诽,我是刑警寧澤商玫,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站牡借,受9級特大地震影響拳昌,放射性物質發(fā)生泄漏。R本人自食惡果不足惜钠龙,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一炬藤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧俊鱼,春花似錦刻像、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至帝火,卻和暖如春溜徙,著一層夾襖步出監(jiān)牢的瞬間湃缎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工蠢壹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嗓违,地道東北人。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓图贸,卻偏偏與公主長得像蹂季,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子疏日,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內容