一.I/O模型名詞介紹
說到I/O模型,都會(huì)牽扯到同步、異步、阻塞、非阻塞這幾個(gè)詞,以下講解這幾個(gè)詞的概念。
阻塞和非阻塞
阻塞和非阻塞指的是一直等還是可以去做其他事。
阻塞(一直等水燒開)(blocking):調(diào)用結(jié)果返回之前,調(diào)用者被掛起(當(dāng)前線程進(jìn)入非可執(zhí)行狀態(tài),在這個(gè)狀態(tài),CPU不會(huì)分配時(shí)間片,線程暫停運(yùn)行);
非阻塞(去看電視,時(shí)不時(shí)看水燒開沒有)(nonblocking):調(diào)用結(jié)果返回之前,調(diào)用者不會(huì)被掛起(當(dāng)前線程還是可執(zhí)行狀態(tài),CPU會(huì)分配時(shí)間片,線程還可以運(yùn)行)
同步和異步
同步/異步關(guān)注的是消息通信機(jī)制
同步(不會(huì)響的水壺)(synchronous):被調(diào)用者完成任務(wù)后,不會(huì)主動(dòng)給調(diào)用者返回調(diào)用結(jié)果。
異步(會(huì)響的水壺)(asynchronous):被調(diào)用者完成任務(wù)后,會(huì)主動(dòng)給調(diào)用者返回調(diào)用結(jié)果。
??????????????????
? ? ?? 阻塞、非阻塞、多路IO復(fù)用,都是同步IO,異步必定是非阻塞的,所以不存在異步阻塞和異步非阻塞的說法。真正的異步IO需要CPU的深度參與。換句話說,只有用戶線程在操作IO的時(shí)候根本不去考慮IO的執(zhí)行全部都交給CPU去完成,而自己只等待一個(gè)完成信號的時(shí)候,才是真正的異步IO。所以,拉一個(gè)子線程去輪詢、去死循環(huán),或者使用select、poll、epool,都不是異步。
二.I/O模型類型
IO模型分為以下五類
- 阻塞I/O:所有過程全阻塞
- 非阻塞I/O:如果沒有數(shù)據(jù)buffer,則立即返回EWOULDBLOCK
- I/O復(fù)用型(select和poll):在wait和copy階段分別阻塞
- 信號驅(qū)動(dòng)型I/O(SIGIO):在wait階段不阻塞,但copy階段阻塞(信號驅(qū)動(dòng)I/O),即通知
- 異步I/O(AIO):完全無阻塞方式,當(dāng)I/O完成時(shí)提供信號
1.阻塞I/O
說明:應(yīng)用程序調(diào)用一個(gè)IO的recvfrom函數(shù),會(huì)導(dǎo)致應(yīng)用程序阻塞,進(jìn)入阻塞狀態(tài)后直到I/O操作結(jié)束才會(huì)返回;如果系統(tǒng)內(nèi)核數(shù)據(jù)沒有準(zhǔn)備好,那就一直等待數(shù)據(jù)準(zhǔn)備,因?yàn)槭钦{(diào)用了recvfrom函數(shù)導(dǎo)致了應(yīng)用程序阻塞,所以一直在等,做不了任何事情,內(nèi)核數(shù)據(jù)準(zhǔn)備好之后把數(shù)據(jù)從內(nèi)核拷貝到用戶空間,拷貝結(jié)束后,I/O函數(shù)返回成功指示。 注:其阻塞時(shí)在I/O操作階段
2.非阻塞I/O
說明:用戶線程發(fā)起IO請求時(shí)立即返回。但并未讀取到任何數(shù)據(jù),則返回字段為“EWOULDBLOCK”,用戶線程需要不斷地發(fā)起IO請求,直到數(shù)據(jù)到達(dá)后,才真正讀取到數(shù)據(jù),繼續(xù)執(zhí)行。即“輪詢”機(jī)制。 整個(gè)IO請求過程中,雖然用戶線程每次發(fā)起IO請求后可以立即返回,但是為了等到數(shù)據(jù)。仍需要不斷地輪詢、重復(fù)請求、消耗了大量的CPU資源;是比較浪費(fèi)CPU的方式,一般很少用這種模型,而是在其他模型中使用非阻塞IO這一特性。
3.I/O復(fù)用(select和poll)
說明:I/O復(fù)用模型會(huì)用到select或poll函數(shù),在I/O復(fù)用模型中,并不是阻塞到I/O操作過程中,而是阻塞到select或者poll函數(shù)中; 以select為例:進(jìn)程在select處阻塞,等待幾個(gè)描述符中的一個(gè)變?yōu)榭刹僮鳎绻麤]等待到就繼續(xù)阻塞在第一階段,如果等到了一個(gè)描述符變?yōu)榱丝刹僮鳎瑒t調(diào)用recvfrom函數(shù)將數(shù)據(jù)拷貝到應(yīng)用緩沖區(qū)。
4.信號驅(qū)動(dòng)I/O(SIGIO)
說明:首先,我們允許套接口進(jìn)行信號驅(qū)動(dòng)I/O,并安裝一個(gè)信號處理函數(shù)SIGIO,如果數(shù)據(jù)沒有準(zhǔn)備好,則立即返回結(jié)果,進(jìn)程繼續(xù)工作并不阻塞。當(dāng)數(shù)據(jù)準(zhǔn)備好時(shí),系統(tǒng)內(nèi)核會(huì)主動(dòng)發(fā)送一個(gè)SIGIO信號給應(yīng)用程序,應(yīng)用程序收到信號后,可以在信號處理函數(shù)中調(diào)用I/O操作函數(shù)recvfrom進(jìn)行數(shù)據(jù)處理。 信號驅(qū)動(dòng)I/O模型的優(yōu)點(diǎn)是當(dāng)數(shù)據(jù)報(bào)到達(dá)時(shí),可以不阻塞,主循環(huán)可以繼續(xù)執(zhí)行,只是等待處理程序的通知,或者數(shù)據(jù)已經(jīng)準(zhǔn)備好被處理,或者數(shù)據(jù)報(bào)已經(jīng)準(zhǔn)備好被讀了。
5.異步I/O(AIO)
說明:當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過狀態(tài)通知和回調(diào)通知來告訴調(diào)用者的輸入輸出操作。 用戶可以直接對I/O執(zhí)行讀寫操作,這些操作告訴內(nèi)核用戶讀寫緩沖區(qū)的位置,以及I/O操作完成之后內(nèi)核通知應(yīng)用程序的方式,就是上面講的通過狀態(tài)通知或者回調(diào)通知來告訴調(diào)用者。異步I/O的讀寫操作總是立即返回,但沒有返回結(jié)果說是否阻塞,因?yàn)楫惒絀/O操作真正的讀寫操作已由內(nèi)核接管,內(nèi)核自己對數(shù)據(jù)處理完成后生成一個(gè)信號,然后通知用戶剛才交給自己的事件已經(jīng)處理完成。
五種I/O模型的總結(jié)及比較
中文圖示如下:
英文圖示如下:
文章來源:http://www.zghlxwxcb.cn/news/detail-656582.html
從兩張圖中我們可以看到,越往后,阻塞越少,理論上效率也是最優(yōu)。 其中五種I/O模型中,前三種屬于同步I/O,后兩者屬于異步I/O。文章來源地址http://www.zghlxwxcb.cn/news/detail-656582.html
到了這里,關(guān)于IO的幾個(gè)模型的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!