<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          理解一下5種IO模型、阻塞IO和非阻塞IO、同步IO和異步IO

          共 3190字,需瀏覽 7分鐘

           ·

          2020-08-18 11:58

          ? ? ?

          ? ?正文? ?

          5種IO模型、阻塞IO和非阻塞IO、同步IO和異步IO

          看了一些文章,發(fā)現(xiàn)有很多不同的理解,可能是因?yàn)榇蠹胰肭械慕嵌取h(huán)境不一樣。所以,我們先說明基本的IO操作及環(huán)境。

          本文是在《UNIX網(wǎng)絡(luò)編程 卷1:套接字聯(lián)網(wǎng)API》6.2節(jié)"I/O 模型 "的基礎(chǔ)上,即UNIX/LINUX環(huán)境下的網(wǎng)絡(luò) IO環(huán)境下的理解,它里面給出的例子是讀取(接收)網(wǎng)絡(luò)UDP數(shù)據(jù)。下面簡單寫寫自己對這些IO模型的理解。

          1、IO

          IO (Input/Output,輸入/輸出)即數(shù)據(jù)的讀取(接收)或?qū)懭耄òl(fā)送)操作,通常用戶進(jìn)程中的一個(gè)完整IO分為兩階段:用戶進(jìn)程空間<-->內(nèi)核空間、內(nèi)核空間<-->設(shè)備空間(磁盤、網(wǎng)絡(luò)等)。IO有內(nèi)存IO、網(wǎng)絡(luò)IO和磁盤IO三種,通常我們說的IO指的是后兩者。

          LINUX中進(jìn)程無法直接操作I/O設(shè)備,其必須通過系統(tǒng)調(diào)用請求kernel來協(xié)助完成I/O動作;內(nèi)核會為每個(gè)I/O設(shè)備維護(hù)一個(gè)緩沖區(qū)。

          對于一個(gè)輸入操作來說,進(jìn)程IO系統(tǒng)調(diào)用后,內(nèi)核會先看緩沖區(qū)中有沒有相應(yīng)的緩存數(shù)據(jù),沒有的話再到設(shè)備中讀取,因?yàn)樵O(shè)備IO一般速度較慢,需要等待;內(nèi)核緩沖區(qū)有數(shù)據(jù)則直接復(fù)制到進(jìn)程空間。

          所以,對于一個(gè)網(wǎng)絡(luò)輸入操作通常包括兩個(gè)不同階段:

          • 等待網(wǎng)絡(luò)數(shù)據(jù)到達(dá)網(wǎng)卡→讀取到內(nèi)核緩沖區(qū),數(shù)據(jù)準(zhǔn)備好;
          • 從內(nèi)核緩沖區(qū)復(fù)制數(shù)據(jù)到進(jìn)程空間。

          2、5種IO模型

          《UNIX網(wǎng)絡(luò)編程》說得很清楚,5種IO模型分別是阻塞IO模型、非阻塞IO模型、IO復(fù)用模型、信號驅(qū)動的IO模型、異步IO模型;前4種為同步IO操作,只有異步IO模型是異步IO操作。

          下面這樣些圖,是它里面給出的例子:接收網(wǎng)絡(luò)UDP數(shù)據(jù)的流程在IO模型下的分析,在它的基礎(chǔ)上再加以簡單描述,以區(qū)分這些IO模型。

          2-1、阻塞IO模型

          進(jìn)程發(fā)起IO系統(tǒng)調(diào)用后,進(jìn)程被阻塞,轉(zhuǎn)到內(nèi)核空間處理,整個(gè)IO處理完畢后返回進(jìn)程。操作成功則進(jìn)程獲取到數(shù)據(jù)。

          關(guān)注公眾號程序員小樂回復(fù)關(guān)鍵字“offer”獲取算法面試題和答案。

          1、典型應(yīng)用:阻塞socket、Java BIO;

          2、特點(diǎn):

          • 進(jìn)程阻塞掛起不消耗CPU資源,及時(shí)響應(yīng)每個(gè)操作;

          • 實(shí)現(xiàn)難度低、開發(fā)應(yīng)用較容易;

          • 適用并發(fā)量小的網(wǎng)絡(luò)應(yīng)用開發(fā);

          不適用并發(fā)量大的應(yīng)用:因?yàn)橐粋€(gè)請求IO會阻塞進(jìn)程,所以,得為每請求分配一個(gè)處理進(jìn)程(線程)以及時(shí)響應(yīng),系統(tǒng)開銷大。

          2-2、非阻塞IO模型

          進(jìn)程發(fā)起IO系統(tǒng)調(diào)用后,如果內(nèi)核緩沖區(qū)沒有數(shù)據(jù),需要到IO設(shè)備中讀取,進(jìn)程返回一個(gè)錯(cuò)誤而不會被阻塞;進(jìn)程發(fā)起IO系統(tǒng)調(diào)用后,如果內(nèi)核緩沖區(qū)有數(shù)據(jù),內(nèi)核就會把數(shù)據(jù)返回進(jìn)程。

          對于上面的阻塞IO模型來說,內(nèi)核數(shù)據(jù)沒準(zhǔn)備好需要進(jìn)程阻塞的時(shí)候,就返回一個(gè)錯(cuò)誤,以使得進(jìn)程不被阻塞。

          1、典型應(yīng)用:socket是非阻塞的方式(設(shè)置為NONBLOCK)

          2、特點(diǎn):

          • 進(jìn)程輪詢(重復(fù))調(diào)用,消耗CPU的資源;

          • 實(shí)現(xiàn)難度低、開發(fā)應(yīng)用相對阻塞IO模式較難;

          • 適用并發(fā)量較小、且不需要及時(shí)響應(yīng)的網(wǎng)絡(luò)應(yīng)用開發(fā);

          2-3、IO復(fù)用模型

          多個(gè)的進(jìn)程的IO可以注冊到一個(gè)復(fù)用器(select)上,然后用一個(gè)進(jìn)程調(diào)用該select, select會監(jiān)聽所有注冊進(jìn)來的IO;

          如果select沒有監(jiān)聽的IO在內(nèi)核緩沖區(qū)都沒有可讀數(shù)據(jù),select調(diào)用進(jìn)程會被阻塞;而當(dāng)任一IO在內(nèi)核緩沖區(qū)中有可數(shù)據(jù)時(shí),select調(diào)用就會返回;

          而后select調(diào)用進(jìn)程可以自己或通知另外的進(jìn)程(注冊進(jìn)程)來再次發(fā)起讀取IO,讀取內(nèi)核中準(zhǔn)備好的數(shù)據(jù)。

          可以看到,多個(gè)進(jìn)程注冊IO后,只有另一個(gè)select調(diào)用進(jìn)程被阻塞。

          1、典型應(yīng)用:select、poll、epoll三種方案,nginx都可以選擇使用這三個(gè)方案;Java NIO;

          2、特點(diǎn):

          • 專一進(jìn)程解決多個(gè)進(jìn)程IO的阻塞問題,性能好;Reactor模式;

          • 實(shí)現(xiàn)、開發(fā)應(yīng)用難度較大;

          • 適用高并發(fā)服務(wù)應(yīng)用開發(fā):一個(gè)進(jìn)程(線程)響應(yīng)多個(gè)請求;

          3、select、poll、epoll

          • Linux中IO復(fù)用的實(shí)現(xiàn)方式主要有select、poll和epoll:

          • Select:注冊IO、阻塞掃描,監(jiān)聽的IO最大連接數(shù)不能多于FD_SIZE;

          • Poll:原理和Select相似,沒有數(shù)量限制,但I(xiàn)O數(shù)量大掃描線性性能下降;

          • Epoll :事件驅(qū)動不阻塞,mmap實(shí)現(xiàn)內(nèi)核與用戶空間的消息傳遞,數(shù)量很大,Linux2.6后內(nèi)核支持;

          2-4、信號驅(qū)動IO模型

          當(dāng)進(jìn)程發(fā)起一個(gè)IO操作,會向內(nèi)核注冊一個(gè)信號處理函數(shù),然后進(jìn)程返回不阻塞;當(dāng)內(nèi)核數(shù)據(jù)就緒時(shí)會發(fā)送一個(gè)信號給進(jìn)程,進(jìn)程便在信號處理函數(shù)中調(diào)用IO讀取數(shù)據(jù)。

          特點(diǎn):回調(diào)機(jī)制,實(shí)現(xiàn)、開發(fā)應(yīng)用難度大;

          2-5、異步IO模型

          當(dāng)進(jìn)程發(fā)起一個(gè)IO操作,進(jìn)程返回(不阻塞),但也不能返回果結(jié);內(nèi)核把整個(gè)IO處理完后,會通知進(jìn)程結(jié)果。如果IO操作成功則進(jìn)程直接獲取到數(shù)據(jù)。

          關(guān)注公眾號程序員小樂回復(fù)關(guān)鍵字“Java”獲取Java面試題和答案。

          1、典型應(yīng)用:JAVA7 AIO、高性能服務(wù)器應(yīng)用

          2、特點(diǎn):

          • 不阻塞,數(shù)據(jù)一步到位;Proactor模式;

          • 需要操作系統(tǒng)的底層支持,LINUX 2.5 版本內(nèi)核首現(xiàn),2.6 版本產(chǎn)品的內(nèi)核標(biāo)準(zhǔn)特性;

          • 實(shí)現(xiàn)、開發(fā)應(yīng)用難度大;

          • 非常適合高性能高并發(fā)應(yīng)用;

          3、IO模型比較

          3-1、阻塞IO調(diào)用和非阻塞IO調(diào)用、阻塞IO模型和非阻塞IO模型

          注意這里的阻塞IO調(diào)用和非阻塞IO調(diào)用不是指阻塞IO模型和非阻塞IO模型:

          • 阻塞IO調(diào)用 :在用戶進(jìn)程(線程)中調(diào)用執(zhí)行的時(shí)候,進(jìn)程會等待該IO操作,而使得其他操作無法執(zhí)行。
          • 非阻塞IO調(diào)用:在用戶進(jìn)程中調(diào)用執(zhí)行的時(shí)候,無論成功與否,該IO操作會立即返回,之后進(jìn)程可以進(jìn)行其他操作(當(dāng)然如果是讀取到數(shù)據(jù),一般就接著進(jìn)行數(shù)據(jù)處理)。

          這個(gè)直接理解就好,進(jìn)程(線程)IO調(diào)用會不會阻塞進(jìn)程自己。所以這里兩個(gè)概念是相對調(diào)用進(jìn)程本身狀態(tài)來講的。

          從上面對比圖片來說,阻塞IO模型是一個(gè)阻塞IO調(diào)用,而非阻塞IO模型是多個(gè)非阻塞IO調(diào)用+一個(gè)阻塞IO調(diào)用,因?yàn)槎鄠€(gè)IO檢查會立即返回錯(cuò)誤,不會阻塞進(jìn)程。

          而上面也說過了,非阻塞IO模型對于阻塞IO模型來說區(qū)別就是,內(nèi)核數(shù)據(jù)沒準(zhǔn)備好需要進(jìn)程阻塞的時(shí)候,就返回一個(gè)錯(cuò)誤,以使得進(jìn)程不被阻塞。

          3-2、同步IO和異步IO

          • 同步IO:導(dǎo)致請求進(jìn)程阻塞,直到I/O操作完成。

          • 異步IO:不導(dǎo)致請求進(jìn)程阻塞。

          上面兩個(gè)定義是《UNIX網(wǎng)絡(luò)編程 卷1:套接字聯(lián)網(wǎng)API》給出的。這不是很好理解,我們來擴(kuò)展一下,先說說同步和異步,同步和異步關(guān)注的是雙方的消息通信機(jī)制:

          • 同步:雙方的動作是經(jīng)過雙方協(xié)調(diào)的,步調(diào)一致的。
          • 異步:雙方并不需要協(xié)調(diào),都可以隨意進(jìn)行各自的操作。

          這里我們的雙方是指,用戶進(jìn)程和IO設(shè)備;明確同步和異步之后,我們在上面網(wǎng)絡(luò)輸入操作例子的基礎(chǔ)上,進(jìn)行擴(kuò)展定義:

          • 同步IO:用戶進(jìn)程發(fā)出IO調(diào)用,去獲取IO設(shè)備數(shù)據(jù),雙方的數(shù)據(jù)要經(jīng)過內(nèi)核緩沖區(qū)同步,完全準(zhǔn)備好后,再復(fù)制返回到用戶進(jìn)程。而復(fù)制返回到用戶進(jìn)程會導(dǎo)致請求進(jìn)程阻塞,直到I/O操作完成。

          • 異步IO:用戶進(jìn)程發(fā)出IO調(diào)用,去獲取IO設(shè)備數(shù)據(jù),并不需要同步,內(nèi)核直接復(fù)制到進(jìn)程,整個(gè)過程不導(dǎo)致請求進(jìn)程阻塞。

          所以, 阻塞IO模型、非阻塞IO模型、IO復(fù)用模型、信號驅(qū)動的IO模型者為同步IO模型,只有異步IO模型是異步IO。


          源:https://blog.csdn.net/tjiyu/article/details/52959418

          版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會立即刪除并表示歉意。謝謝!





          感謝閱讀



          瀏覽 52
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美熟妇xxxxxx | 中文字幕+乱码+中文乱码视频在线观看 | 啊啊啊操B视频在线观看 | 欧美日韩视频在线 | 亚洲黄色成人在线 |