Linux五種IO模型

socket阻塞與非阻塞,同步與異步
https://blog.csdn.net/u010177010/article/details/50969543
https://blog.csdn.net/jay900323/article/details/18141217

1. 概念介紹:

  • 同步:
    所謂同步,就是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回。也就是必須一件一件事做,等前一件做完了才能做下一件事。

  • 異步:
    異步的概念和同步相對。當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果。實(shí)際處理這個(gè)調(diào)用的部件在完成后,通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。

  • 阻塞:
    阻塞調(diào)用是指調(diào)用結(jié)果返回之前,當(dāng)前線程會(huì)被掛起(線程進(jìn)入非可執(zhí)行狀態(tài),在這個(gè)狀態(tài)下,cpu不會(huì)給線程分配時(shí)間片,即線程暫停運(yùn)行)。函數(shù)只有在得到結(jié)果之后才會(huì)返回。
    有人也許會(huì)把阻塞調(diào)用和同步調(diào)用等同起來,實(shí)際上他是不同的。對于同步調(diào)用來說,很多時(shí)候當(dāng)前線程還是激活的,只是從邏輯上當(dāng)前函數(shù)沒有返回而已。 例如,我們在socket中調(diào)用recv函數(shù),如果緩沖區(qū)中沒有數(shù)據(jù),這個(gè)函數(shù)就會(huì)一直等待,直到有數(shù)據(jù)才返回。而此時(shí),當(dāng)前線程還會(huì)繼續(xù)處理各種各樣的消息。

  • 非阻塞:
    非阻塞和阻塞的概念相對應(yīng),指在不能立刻得到結(jié)果之前,該函數(shù)不會(huì)阻塞當(dāng)前線程,而會(huì)立刻返回。
    對象的阻塞模式和阻塞函數(shù)調(diào)用對象是否處于阻塞模式和函數(shù)是不是阻塞調(diào)用有很強(qiáng)的相關(guān)性,但是并不是一一對應(yīng)的。阻塞對象上可以有非阻塞的調(diào)用方式,我們可以通過一定的API去輪詢狀態(tài),在適當(dāng)?shù)臅r(shí)候調(diào)用阻塞函數(shù),就可以避免阻塞。而對于非阻塞對象,調(diào)用特殊的函數(shù)也可以進(jìn)入阻塞調(diào)用。函數(shù)select就是這樣的一個(gè)例子。

    總結(jié): 
    1. 同步,就是我調(diào)用一個(gè)功能,該功能沒有結(jié)束前,我死等結(jié)果。
    2. 異步,就是我調(diào)用一個(gè)功能,不需要知道該功能結(jié)果,該功能有結(jié)果后通知我(回調(diào)通知)。
    3. 阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))沒有接收完數(shù)據(jù)或者沒有得到結(jié)果之前,我不會(huì)返回。
    4. 非阻塞,就是調(diào)用我(函數(shù)),我(函數(shù))立即返回,通過select通知調(diào)用者。
    同步IO和異步IO的區(qū)別就在于:數(shù)據(jù)拷貝的時(shí)候進(jìn)程是否阻塞!
    阻塞IO和非阻塞IO的區(qū)別就在于:應(yīng)用程序的調(diào)用是否立即返回!
    
同步和異步、阻塞和非阻塞如何區(qū)分?

同步和異步,阻塞和非阻塞,有些混用,其實(shí)它們完全不是一回事,而且它們修飾的對象也不相同。

阻塞和非阻塞是指當(dāng)進(jìn)程訪問的數(shù)據(jù)如果尚未就緒,進(jìn)程是否需要等待,簡單說這相當(dāng)于函數(shù)內(nèi)部的實(shí)現(xiàn)區(qū)別,也就是未就緒時(shí)是直接返回還是等待就緒;

而同步和異步是指訪問數(shù)據(jù)的機(jī)制,同步一般指主動(dòng)請求并等待I/O操作完畢的方式,當(dāng)數(shù)據(jù)就緒后在讀寫的時(shí)候必須阻塞(區(qū)別就緒與讀寫二個(gè)階段,同步的讀寫必須阻塞),異步則指主動(dòng)請求數(shù)據(jù)后便可以繼續(xù)處理其它任務(wù),隨后等待I/O,操作完畢的通知,這可以使進(jìn)程在數(shù)據(jù)讀寫時(shí)也不阻塞。(等待"通知")

2. Linux下的五種I/O模型

http://www.itdecent.cn/p/6a6845464770

  1. 阻塞I/O(blocking I/O)
  2. 非阻塞I/O (nonblocking I/O)
  3. I/O復(fù)用(select 和poll) (I/O multiplexing)
  4. 信號(hào)驅(qū)動(dòng)I/O (signal driven I/O (SIGIO))
  5. 異步I/O (asynchronous I/O (the POSIX aio_functions))
    前四種都是同步,只有最后一種才是異步IO。
2.1 阻塞I/O模型

特點(diǎn):進(jìn)程會(huì)一直阻塞,直到數(shù)據(jù)拷貝完成

阻塞I/O模型
2.2 非阻塞IO模型

特點(diǎn):非阻塞IO通過進(jìn)程反復(fù)調(diào)用IO函數(shù)(多次系統(tǒng)調(diào)用,并馬上返回);在數(shù)據(jù)拷貝的過程中,進(jìn)程是阻塞的

非阻塞I/O模型
2.3 I/O復(fù)用模型

特點(diǎn):主要是select和epoll;對一個(gè)IO端口,兩次調(diào)用,兩次返回,比阻塞IO并沒有什么優(yōu)越性;關(guān)鍵是能實(shí)現(xiàn)同時(shí)對多個(gè)IO端口進(jìn)行監(jiān)聽

I/O復(fù)用模型

當(dāng)用戶進(jìn)程調(diào)用了select,那么整個(gè)進(jìn)程會(huì)被block,而同時(shí),內(nèi)核會(huì)“監(jiān)視”所有select負(fù)責(zé)的socket,當(dāng)任何一個(gè)socket中的數(shù)據(jù)準(zhǔn)備好了,select就會(huì)返回。這個(gè)時(shí)候用戶進(jìn)程再調(diào)用read操作,將數(shù)據(jù)從kernel拷貝到用戶進(jìn)程。

這個(gè)圖和阻塞IO的圖其實(shí)并沒有太大的不同,事實(shí)上,還更差一些。因?yàn)檫@里需要使用兩個(gè)系統(tǒng)調(diào)用 (select 和 recvfrom),而阻塞IO只調(diào)用了一個(gè)系統(tǒng)調(diào)用 (recvfrom)。但是,用select的優(yōu)勢在于它可以同時(shí)處理多個(gè)connection。(多說一句。所以,如果處理的連接數(shù)不是很高的話,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延遲還更大。select/epoll的優(yōu)勢并不是對于單個(gè)連接能處理得更快,而是在于能處理更多的連接。)

在IO 多路復(fù)用中,實(shí)際中,對于每一個(gè)socket,一般都設(shè)置成為非阻塞,但是,如上圖所示,整個(gè)用戶的process其實(shí)是一直被block的。只不過進(jìn)程是被select這個(gè)函數(shù)block,而不是被socket IO給block。

2.4 信號(hào)驅(qū)動(dòng)I/O模型

特點(diǎn):兩次調(diào)用,兩次返回;
首先我們允許套接口進(jìn)行信號(hào)驅(qū)動(dòng)I/O,并安裝一個(gè)信號(hào)處理函數(shù),進(jìn)程繼續(xù)運(yùn)行并不阻塞。當(dāng)數(shù)據(jù)準(zhǔn)備好時(shí),進(jìn)程會(huì)收到一個(gè)SIGIO信號(hào),可以在信號(hào)處理函數(shù)中調(diào)用I/O操作函數(shù)處理數(shù)據(jù)。

信號(hào)驅(qū)動(dòng)I/O模型
2.5 異步I/O模型

特點(diǎn):數(shù)據(jù)拷貝的時(shí)候進(jìn)程無需阻塞。

異步I/O模型
2.6 幾個(gè)形象形象比喻

下面引用知乎一書焚城的回答再次鞏固一下IO模型

  1. 阻塞IO, 給女神發(fā)一條短信, 說我來找你了, 然后就默默的一直等著女神下樓, 這個(gè)期間除了等待你不會(huì)做其他事情, 屬于備胎做法.
  1. 非阻塞IO, 給女神發(fā)短信, 如果不回, 接著再發(fā), 一直發(fā)到女神下樓, 這個(gè)期間你除了發(fā)短信等待不會(huì)做其他事情, 屬于專一做法.
  1. IO多路復(fù)用, 是找一個(gè)宿管大媽來幫你監(jiān)視下樓的女生, 這個(gè)期間你可以些其他的事情. 例如可以順便看看其他妹子,玩玩王者榮耀, 上個(gè)廁所等等. IO復(fù)用又包括 select, poll, epoll 模式. 那么它們的區(qū)別是什么?
    3.1 select大媽 每一個(gè)女生下樓, select大媽都不知道這個(gè)是不是你的女神, 她需要一個(gè)一個(gè)詢問, 并且select大媽能力還有限, 最多一次幫你監(jiān)視1024個(gè)妹子
    3.2 poll大媽不限制盯著女生的數(shù)量, 只要是經(jīng)過宿舍樓門口的女生, 都會(huì)幫你去問是不是你女神
    3.3 epoll大媽不限制盯著女生的數(shù)量, 并且也不需要一個(gè)一個(gè)去問. 那么如何做呢? epoll大媽會(huì)為每個(gè)進(jìn)宿舍樓的女生臉上貼上一個(gè)大字條,上面寫上女生自己的名字, 只要女生下樓了, epoll大媽就知道這個(gè)是不是你女神了, 然后大媽再通知你.

上面這些同步IO有一個(gè)共同點(diǎn)就是, 當(dāng)女神走出宿舍門口的時(shí)候, 你已經(jīng)站在宿舍門口等著女神的, 此時(shí)你屬于阻塞狀態(tài)

接下來是異步IO的情況
你告訴女神我來了, 然后你就去王者榮耀了, 一直到女神下樓了, 發(fā)現(xiàn)找不見你了, 女神再給你打電話通知你, 說我下樓了, 你在哪呢? 這時(shí)候你才來到宿舍門口. 此時(shí)屬于逆襲做法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容