<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] ## 概述 在介紹這兩種模型之前先介紹一下在I/O場景下同步、異步、阻塞、非阻塞的概念。 我們都知道我們的程序是運行在操作系統上的,我們程序和服務器硬件之間隔著個操作系統,一般情況下我們的服務器都是linux系統,為了安全考慮linux系統又分了:**用戶態和內核態**。 I/O操作得經歷兩個過程: 1、讀存儲設備數據到內核緩存 2、從內核緩存讀數據到用戶空間 >1操作比2操作慢的多,因為去磁盤尋址啊等操作比較慢。 然后我們**平日里針對I/O場景下說的阻塞I/O、非阻塞I/O指的就是1操作是否阻塞**,也就是會立即返回一個狀態值,還是會等待存儲設備數據讀取到內核緩存后在返回所需的數據。 而平日里說的**同步I/O、異步I/O指的是2操作是否會阻塞。** 我們提到不同的操作系統實現的io策略可能不一樣,即使是同一個操作系統也可能存在多重io策略,常見如linux上的select,poll,epoll,面對這么多不同類型的io接口,這里需要一層抽象api來完成,所以就演變出來兩種高性能的io的設計模式,分別是Reactor(同步IO)和Proactor(異步IO)。 一般情況下,I/O 復用機制需要事件分享器(event demultiplexor)。 事件分離器的作用,即將那些讀寫事件源分發給各讀寫事件的處理者,就像送快遞的小哥,拉著一三輪車快遞停到了小區的快遞收發區,然后打電話通知,誰誰誰的快遞到了快來拿吧;誰誰誰要郵寄出去的快遞,快來這里郵寄填寫表格。這里面拿快遞就類似IO的讀請求,發快遞就類似IO的寫請求,而快遞小哥則是事件分享器,并負責完成送和收快遞的兩種事件。開發人員在開始的時候需要在分享器那里注冊感興趣的事件,并提供相應的處理者(event handlers),或者是回調函數; 事件分享器在適當的時候會將請求的事件分發給這些handler或者回調函數。 ## 關于Reactor Reactor英文意思為反應器,類似于核能的反應堆一樣,所有的能量都源源不斷從這里傳出.或者更貼切一點叫事件的分發器。在Reactor中,事件分離器負責等待文件描述符或socket為讀寫操作準備就緒,然后將就緒事件傳遞給對應的處理器,最后由處理器負責完成實際的讀寫工作。 Linux epoll 使用 Reactor 模式。Reactor 模式使用同步 I/O(一般來說)。Reactor 的標準(典型)的工作方式是: (1)應用程序注冊讀就緒事件和相關聯的事件處理器 (2)Reactor阻塞等待內核事件通知 (3)Reactor收到通知,然后分發可讀寫事件(讀寫準備就緒)到用戶事件處理函數 (4)用戶讀取數據,并處理數據 (5)事件處理器完成實際的讀操作,處理讀到的數據,注冊新的事件,然后返還控制權。 這里面需要注意,事件分離器僅僅發現當有io事件都寫就緒的時候,會通知用戶線程來讀取數據,這一步相當于io阻塞的第二個階段,從內核空間拷貝數據到用戶空間是由用戶線程完成的,所以Reactor模式實際上還屬于同步IO的模式,當然為了架構更靈活和性能更好,一般情況下事件分離器和實際的處理器線程是分開的,類似Netty里面的boss線程組合worker線程組一樣。 ## 關于Proactor Proactor英文意思前攝器,是一種異步的IO設計模式。這種模式更加理想,但真正支持純異步的io模式,目前只有windows的Windows IO completion port.(iocp)模型。 Windows iocp 使用 Proactor 模式。Proactor 模式使用異步 I/O(一般來說)。Proactor 的標準(典型)的工作方式是: (1)應用程序初始化一個異步讀取操作,然后注冊相應的事件處理器,此時事件處理器不關注讀取就緒事件,而是關注讀取完成事件,這是區別于Reactor的關鍵。 (2)事件分離器等待讀取操作完成事件 (3)在事件分離器等待讀取操作完成的時候,操作系統調用內核線程完成讀取操作,并將讀取的內容放入用戶傳遞過來的緩存區中。這也是區別于Reactor的一點,Proactor中,應用程序需要傳遞緩存區。 (4)事件分離器捕獲到讀取完成事件后,激活應用程序注冊的事件處理器,事件處理器直接從緩存區讀取數據,而不需要進行實際的讀取操作。 從上面的描述中能夠看到,Proactor模式中,操作系統相當于直接把IO操作的兩階段工作都給干了,這也要求應用程序在注冊異步任務時,需要傳遞一個緩存區,用來存放結果數據。這里面事件分離器關注的是io的完成事件,而不是就緒時間,當分離器通知應用程序時,應用程序可以直接就能處理數據了。 ## 總結 關于Reactor和Proactor這兩種IO設計模式,我們舉個實際生活中的例子:Reactor模式就是快遞員在樓下,給你打電話告訴你快遞到了,你需要自己下樓來拿快遞。而在Proactor模式下,快遞員直接將快遞送到家里面的指定位置。 Reactor和Proactor是兩種高性能的IO設計模式,分別用于同步IO和異步IO的策略,可以看出它們都是采用的IO復用的模式,都是對某個IO事件的事件通知(即告訴某個模塊,這個IO操作可以進行或已經完成)。在結構上,兩者也有相同點:demultiplexor負責提交IO操作(異步)、查詢設備是否可操作(同步),然后當條件滿足時,就回調handler; 不同點在于,異步情況下(Proactor),當回調handler時,表示IO操作已經完成(數據已從系統內核拷貝到程序內存);同步情況下(Reactor),回調handler時,表示IO設備可以進行某個操作(can read or can write,數據準備就緒,但是用戶需要自己將數據從系統內核拷貝到程序內存)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看