IO模型
同步鹏往、異步、阻塞骇塘、非阻塞
socket阻塞與非阻塞伊履,同步與異步
同步和異步
同步/異步主要針對(duì)C端
-同步
就像普通的頁面,在頁面發(fā)送post過去之后款违,到收到頁面返回的信息唐瀑。這整一個(gè)動(dòng)作是同步的
-異步
瀏覽器如果是通過ajax和服務(wù)器進(jìn)行交互的。這個(gè)步驟就是異步的插爹。
同步IO和異步IO的區(qū)別在于:數(shù)據(jù)訪問的時(shí)候進(jìn)程是否阻塞
阻塞和非阻塞
-阻塞
用戶向Web服務(wù)器發(fā)送一個(gè)請(qǐng)求哄辣,web服務(wù)器向數(shù)據(jù)庫請(qǐng)求這個(gè)請(qǐng)求请梢,然后一直等數(shù)據(jù)庫返回結(jié)果,在得到結(jié)果后講數(shù)據(jù)返回給用戶力穗。
-非阻塞
一個(gè)用戶向Web服務(wù)器發(fā)送一個(gè)請(qǐng)求毅弧,Web服務(wù)器告訴數(shù)據(jù)庫我要一個(gè)什么樣的東西,然后Web服務(wù)器做其他的事情当窗,數(shù)據(jù)庫完成之后告訴(通知够坐、回調(diào)、狀態(tài))Web服務(wù)器崖面,Web回來接受訊息元咙,然后把結(jié)果返回給用戶。
阻塞IO和非阻塞IO的區(qū)別在于:應(yīng)用程序的調(diào)用是否立即返回
-阻塞I/O
-非阻塞I/O
-I/O復(fù)用
-信號(hào)驅(qū)動(dòng)I/O
-異步I/O
前四種都是同步巫员,只有最后一種是異步蛾坯。
阻塞I/O模型
進(jìn)程會(huì)一直阻塞,直到數(shù)據(jù)拷貝完成
進(jìn)程掛起疏遏,阻塞整個(gè)I/O
大伯等郵件 郵遞員沒有來就一直等
非阻塞I/O模型
非阻塞IO通過進(jìn)程反復(fù)調(diào)用IO函數(shù)
采用輪詢,占用CPU
大伯跑到一樓后發(fā)現(xiàn)沒有新郵件救军,他便跑回自己的住房财异,然后又跑下來看有沒有新郵件,沒有的話又跑回去…如此反復(fù)的爬上爬下直到有新的郵件來為止
I/O復(fù)用
主要是select和epoll唱遭,對(duì)一個(gè)IO端口戳寸,兩次調(diào)用,兩次返回拷泽,和阻塞IO相比沒有什么優(yōu)越性疫鹊,能實(shí)現(xiàn)對(duì)多個(gè)IO端口進(jìn)行監(jiān)聽。
多個(gè)連接共用一個(gè)等待機(jī)制
好比一個(gè)小區(qū)的郵件收發(fā)室司致,當(dāng)有新的郵件到達(dá)時(shí)拆吆,值班員會(huì)通知響應(yīng)的人來領(lǐng)取這個(gè)郵件。
信號(hào)驅(qū)動(dòng)IO模型
首先開啟套接口信號(hào)驅(qū)動(dòng)IO功能脂矫,通過系統(tǒng)調(diào)用sigation執(zhí)行一個(gè)信號(hào)處理函數(shù)(此信號(hào)調(diào)用直接返回枣耀,進(jìn)程繼續(xù)工作)。當(dāng)數(shù)據(jù)準(zhǔn)備就緒時(shí)庭再,生成一個(gè)signal信號(hào)捞奕,通知應(yīng)用程序來取數(shù)據(jù)。
異步IO
告知內(nèi)核啟動(dòng)某個(gè)操作拄轻,并讓內(nèi)核在整個(gè)操作完成的的那個(gè)之后(將數(shù)據(jù)從內(nèi)核復(fù)制到用戶自己的緩沖區(qū))颅围,進(jìn)行通知
和信號(hào)驅(qū)動(dòng)模型的主要區(qū)別室:信號(hào)驅(qū)動(dòng)IO由內(nèi)核通知我們合適可以開始一個(gè)IO操作在client進(jìn)行IO操作的時(shí)候需要等待,所以是同步的恨搓。異步IO模型由內(nèi)核通知我們IO何時(shí)已經(jīng)完成,client不需要進(jìn)行IO的處理了院促,所以是異步的。
別人的總結(jié)
阻塞IO
這是我們熟悉的IO模型,一個(gè)進(jìn)程在作IO操作時(shí)一疯,非要等到數(shù)據(jù)從內(nèi)核空間拷貝到用戶進(jìn)程空間撼玄,才會(huì)返回。這個(gè)模型的優(yōu)點(diǎn)就是簡單墩邀,而且在阻塞的時(shí)候掌猛,CPU還可以進(jìn)行調(diào)度,去執(zhí)行別的進(jìn)程眉睹。
非阻塞IO
一開始我看是非阻塞IO荔茬,覺得應(yīng)該要比阻塞IO模型先進(jìn),可是當(dāng)我一看使用方法的時(shí)候竹海,就知道這個(gè)模型是不會(huì)被實(shí)際使用的慕蔚,僅僅只能作為理論上存在的IO模型。這個(gè)模型的觀點(diǎn)是:進(jìn)行IO操作的時(shí)候斋配,不阻塞孔飒,如果沒有數(shù)據(jù)準(zhǔn)備好,就直接返回錯(cuò)誤碼(或者是別的代碼)艰争。因此坏瞄,使用者就只能不斷進(jìn)行輪詢來調(diào)用IO函數(shù)。這樣的后果就是甩卓,不僅在宏觀上形成了與阻塞IO一共的“阻塞”效果鸠匀,而且在微觀上,CPU一直被用來輪詢逾柿,造成了CPU的浪費(fèi)缀棍。所以,這個(gè)模型還不如阻塞IO模型實(shí)用机错。
IO復(fù)用
對(duì)于IO復(fù)用爬范,我的理解有三點(diǎn):
在一次系統(tǒng)調(diào)用中,實(shí)現(xiàn)了詢問多個(gè)描述符的IO準(zhǔn)備情況 —— 根據(jù)事件通知
為了實(shí)現(xiàn)第一點(diǎn)弱匪,就需要把阻塞的地方進(jìn)行轉(zhuǎn)移坦敌。把一次系統(tǒng)調(diào)用,分為兩次系統(tǒng)調(diào)用痢法。第一次系統(tǒng)調(diào)用可以詢問多個(gè)描述符的IO準(zhǔn)備情況狱窘,在這個(gè)地方進(jìn)行阻塞;而第二次系統(tǒng)調(diào)用财搁,是針對(duì)已經(jīng)準(zhǔn)備好IO的描述符進(jìn)行調(diào)用蘸炸,此時(shí),理論上(按照我的理解)尖奔,也是會(huì)發(fā)生阻塞的搭儒,只不過是此時(shí)內(nèi)核已經(jīng)把數(shù)據(jù)準(zhǔn)備好了穷当,阻塞的時(shí)間可以忽略不計(jì)罷了。
本質(zhì)上淹禾,還是阻塞的馁菜。
信號(hào)IO
我們都知道,信號(hào)是UNIX提供了進(jìn)程間進(jìn)行通信的一種方式铃岔。我們常用的 kill -9 命令(kill是向進(jìn)程傳遞信號(hào)量汪疮,9只是眾多信號(hào)中的一個(gè)代號(hào)),或者是 Ctrl + C 的時(shí)候毁习,就是向某個(gè)進(jìn)程發(fā)出終止的信號(hào)智嚷,這樣進(jìn)程就退出了。
而對(duì)于信號(hào)IO的模型纺且,我是這么理解的:進(jìn)程在發(fā)起IO操作盏道,系統(tǒng)調(diào)用之后,直接訪問载碌,內(nèi)核會(huì)在IO數(shù)據(jù)準(zhǔn)備好之后猜嘱,以某個(gè)信號(hào)通知發(fā)起IO操作的進(jìn)程,從而使得該進(jìn)程的信號(hào)處理函數(shù)可以讀取IO數(shù)據(jù)的操作嫁艇。
本質(zhì)上泉坐,這也是阻塞的IO模型,因?yàn)樵谛盘?hào)處理函數(shù)中裳仆,同樣也是要進(jìn)行阻塞的,只是在在這個(gè)時(shí)候發(fā)起系統(tǒng)系統(tǒng)孤钦,內(nèi)核已經(jīng)把數(shù)據(jù)準(zhǔn)備好了歧斟。
異步IO
這是真正的異步IO了。實(shí)現(xiàn)的機(jī)制是:用戶在發(fā)起異步IO的系統(tǒng)調(diào)用時(shí)偏形,會(huì)把相應(yīng)的數(shù)據(jù)處理函數(shù)作為回調(diào)函數(shù)静袖,等到IO數(shù)據(jù)準(zhǔn)備好,內(nèi)核會(huì)主動(dòng)調(diào)用此回調(diào)函數(shù)俊扭《映龋可以看出,用戶進(jìn)程在這種模型下萨惑,只調(diào)用了一次系統(tǒng)調(diào)用捐康,而且是立即返回的,因此庸蔼,就不會(huì)出現(xiàn)讓進(jìn)程阻塞的情況解总,也就符合了POSIX中異步IO的定義。
其實(shí)我理解起來姐仅,思路是和信號(hào)IO差不多的花枫,唯一不同的地方刻盐,對(duì)于IO數(shù)據(jù)的操作,異步IO是由內(nèi)核主動(dòng)發(fā)起的劳翰,而信號(hào)IO是由用戶進(jìn)程發(fā)起的敦锌。