Python篇-IO多路復(fù)用詳解

TZ : 我是一個(gè)平凡的人,夢(mèng)想開一家甜品店

一 : 科普一分鐘

IO多路復(fù)用IO模式的一種,是一種單線程處理多并發(fā)的IO操作的方案,其他IO操作方案分別有 :

  • 阻塞 I/O(blocking IO)
  • 非阻塞 I/O(nonblocking IO)
  • I/O 多路復(fù)用( IO multiplexing)
  • 異步 I/O(asynchronous IO)

IO多路復(fù)用其實(shí)就是我們說(shuō)的select寥院,poll隘击,epoll,它的基本原理就是select执泰,poll品抽,epoll這個(gè)function會(huì)不斷的輪詢所負(fù)責(zé)的所有socket杉女,當(dāng)某個(gè)socket有數(shù)據(jù)到達(dá)了码耐,就通知用戶進(jìn)程巍举。

select會(huì)輪詢檢測(cè)所有的連接,或者 IO,其理論所使用的就是事件驅(qū)動(dòng)模型這一編程范式

二 : 事件驅(qū)動(dòng)模型與IO多路復(fù)用關(guān)系

  • 事件驅(qū)動(dòng)模型 :

好比中午全體員工1000人去飯,點(diǎn)餐完畢后我們回到座位,飯做好了服務(wù)員就會(huì)叫我們對(duì)應(yīng)點(diǎn)餐的人去取餐.

目前大部分的UI編程都是事件驅(qū)動(dòng)模型,如很多UI平臺(tái)都會(huì)提供onClick()事件蛋逾,這個(gè)事件就代表鼠標(biāo)按下事件集晚。事件驅(qū)動(dòng)模型大體思路如下:

  1. 有一個(gè)事件(消息)隊(duì)列;
  2. 鼠標(biāo)按下時(shí)换怖,往這個(gè)隊(duì)列中增加一個(gè)點(diǎn)擊事件(消息);
  3. 有個(gè)循環(huán)蟀瞧,不斷從隊(duì)列取出事件沉颂,根據(jù)不同的事件,調(diào)用不同的函數(shù)悦污,如onClick()铸屉、onKeyDown()等;
  4. 事件(消息)一般都各自保存各自的處理函數(shù)指針切端,這樣彻坛,每個(gè)消息都有獨(dú)立的處理函數(shù);

IO多路復(fù)用所用的編程范式就是事件驅(qū)動(dòng)模型,是一種監(jiān)測(cè)回調(diào)
封裝好的select(拿select舉例)會(huì)不斷詢問處理,我們所放入的IO事件,哪個(gè)有數(shù)據(jù),就返回.我們就可以拿到了.

協(xié)程也使用了事件驅(qū)動(dòng)模型來(lái)繞過IO事件,遇到IO事件放入操作系統(tǒng)的讀取IO列表,然后操作系統(tǒng)處理好給我們返回.

三 : 異步IO與同步IO

  • 同步IO
    1.阻塞 I/O(blocking IO)
    2.非阻塞 I/O(nonblocking IO)
    3.I/O 多路復(fù)用( IO multiplexing)

為什么會(huì)發(fā)生阻塞呢?其根本原因就是當(dāng)數(shù)據(jù)準(zhǔn)備好之后,內(nèi)核態(tài)用戶態(tài)轉(zhuǎn)發(fā)的時(shí)候呼叫進(jìn)程來(lái)接受,這個(gè)轉(zhuǎn)化的過程是耗時(shí)的操作,等轉(zhuǎn)發(fā)結(jié)束后,阻塞接受

  • 異步IO
    為什么異步是沒有阻塞的操作呢,其根本原因也是因?yàn)?在內(nèi)核態(tài)用戶態(tài)轉(zhuǎn)發(fā)結(jié)束后,才叫進(jìn)程來(lái)接收,進(jìn)程不用等待,直接拿到數(shù)據(jù).

  • 同步異步區(qū)別
    同步IO快餐性質(zhì)餐好了以后你過去取食物,拿食物回到座位,這個(gè)過程是耗時(shí)的操作.
    異步IO大餐性質(zhì),我們餐好了以后,大家還在座位上聊天,服務(wù)員就會(huì)把食物端到桌子上,然后我們吃就可以了,高端服務(wù).

異步IO

解析 :
我們可以用IO多路復(fù)用寫一個(gè)SocketServer實(shí)現(xiàn)單線程下的大并發(fā).
但是IO多路復(fù)用本質(zhì)是還是同步IO,因?yàn)閿?shù)據(jù)從內(nèi)核態(tài)用戶態(tài)的拷貝需要等待操作系統(tǒng)完成,只有異步 I/O本質(zhì)是是異步IO,本質(zhì)上異步 I/O會(huì)當(dāng)數(shù)據(jù)從內(nèi)核態(tài)拷貝到用戶態(tài)這一過程完成之后再去通知程序直接取走,因?yàn)?code>I/O操作是系統(tǒng)完成,所以這才是真正意義上的異步IO操作.

四 : IO多路復(fù)用socketServer

利用IO多路復(fù)用寫一個(gè)socketServer,大多數(shù)情況下機(jī)幾乎很難用到,因?yàn)橛性S許多多模塊和框架已經(jīng)為我們封裝好了,簡(jiǎn)單了解一下底層的實(shí)踐即可.

# Author:TianTianBaby
import  select
import socket
import  queue

#創(chuàng)建socket連接
server = socket.socket()
server.bind(('localhost',9000))
server.listen(1000)

#設(shè)置非阻塞模式
server.setblocking(False)

#key 為接受消息對(duì)象實(shí)例,key 為接受的數(shù)據(jù)
mes_dic = {}

#需要檢測(cè)的連接列表
inputs = [server,]

#返回上一次的數(shù)據(jù)列表
outputs = []

while True:
    readable,writeable,exceptional = select.select(inputs,outputs,inputs)

    for r in  readable:
        if r is server:#代表來(lái)了一個(gè)新連接
            conn,addr = server.accept()
            inputs.append(conn)#因?yàn)樾陆⒌倪B接還沒發(fā)數(shù)據(jù)過來(lái),現(xiàn)在就接受的話程序就報(bào)錯(cuò)
            #所以要想實(shí)現(xiàn)這個(gè)客戶端發(fā)數(shù)據(jù)時(shí)server端能知道,就需要讓select再監(jiān)測(cè)
            #初始化一個(gè)隊(duì)列,后面存要返回給這個(gè)客戶端的數(shù)據(jù)
            mes_dic[conn] = queue.Queue()
        else:
           data = r.recv(1024)
           mes_dic[r].put(data)
           #放入返回的連接隊(duì)列里
           outputs.append(r)

    #要返回給客戶端的連接列表
    for w in writeable:
        data_to_client = mes_dic[w].get()
        #返回給客戶端源數(shù)據(jù)
        w.send(data_to_client)

        #確保下次循環(huán)的時(shí)候writeable,不反回這個(gè)已經(jīng)處理完的連接
        outputs.remove(w)

    #異常
    for e in exceptional:
        if e in outputs:
            outputs.remove(e)
        inputs.remove(e)
        del  mes_dic[e]

五 : 總結(jié)

select踏枣,poll昌屉,epoll都是IO多路復(fù)用的機(jī)制。I/O多路復(fù)用就是通過一種機(jī)制茵瀑,一個(gè)進(jìn)程可以監(jiān)視多個(gè)描述符间驮,一旦某個(gè)描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進(jìn)行相應(yīng)的讀寫操作马昨。但select竞帽,pollepoll本質(zhì)上都是同步I/O鸿捧,因?yàn)樗麄兌夹枰谧x寫事件就緒后自己負(fù)責(zé)進(jìn)行讀寫屹篓,也就是說(shuō)這個(gè)讀寫過程是阻塞的,而異步I/O則無(wú)需自己負(fù)責(zé)進(jìn)行讀寫匙奴,異步I/O的實(shí)現(xiàn)會(huì)負(fù)責(zé)把數(shù)據(jù)從內(nèi)核拷貝到用戶空間堆巧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子恳邀,更是在濱河造成了極大的恐慌懦冰,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谣沸,死亡現(xiàn)場(chǎng)離奇詭異刷钢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乳附,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門内地,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人赋除,你說(shuō)我怎么就攤上這事阱缓。” “怎么了举农?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵荆针,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我颁糟,道長(zhǎng)铅乡,這世上最難降的妖魔是什么律秃? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任外潜,我火速辦了婚禮精续,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘婚脱。我一直安慰自己今魔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布障贸。 她就那樣靜靜地躺著错森,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篮洁。 梳的紋絲不亂的頭發(fā)上问词,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音嘀粱,去河邊找鬼激挪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锋叨,可吹牛的內(nèi)容都是我干的垄分。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼娃磺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼薄湿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤豺瘤,失蹤者是張志新(化名)和其女友劉穎吆倦,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坐求,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蚕泽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了桥嗤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片须妻。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖泛领,靈堂內(nèi)的尸體忽然破棺而出荒吏,到底是詐尸還是另有隱情,我是刑警寧澤渊鞋,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布绰更,位于F島的核電站,受9級(jí)特大地震影響锡宋,放射性物質(zhì)發(fā)生泄漏儡湾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一员辩、第九天 我趴在偏房一處隱蔽的房頂上張望盒粮。 院中可真熱鬧鸵鸥,春花似錦奠滑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至讼油,卻和暖如春杰赛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背矮台。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工乏屯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瘦赫。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓辰晕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親确虱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子含友,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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