天天看點

Reactor和Proactor網絡程式設計模型1、标準定義2、通俗了解3、IO設計模式:Reactor和Proactor對比

連結:https://www.zhihu.com/question/26943938/answer/68773398

reactor:能收了你跟俺說一聲。

proactor: 你給我收十個位元組,收好了跟俺說一聲。

1、标準定義

兩種I/O多路複用模式:Reactor和Proactor

一般地,I/O多路複用機制都依賴于一個事件多路分離器(Event Demultiplexer)。分離器對象可将來自事件源的I/O事件分離出來,并分發到對應的read/write事件處理器(Event Handler)。開發人員預先注冊需要處理的事件及其事件處理器(或回調函數);事件分離器負責将請求事件傳遞給事件處理器。

兩個與事件分離器有關的模式是Reactor和Proactor。Reactor模式采用同步IO,而Proactor采用異步IO。

在Reactor中,事件分離器負責等待檔案描述符或socket為讀寫操作準備就緒,然後将就緒事件傳遞給對應的處理器,最後由處理器負責完成實際的讀寫工作。

而在Proactor模式中,處理器--或者兼任處理器的事件分離器,隻負責發起異步讀寫操作。IO操作本身由作業系統來完成。傳遞給作業系統的參數需要包括使用者定義的資料緩沖區位址和資料大小,作業系統才能從中得到寫出操作所需資料,或寫入從socket讀到的資料。事件分離器捕獲IO操作完成事件,然後将事件傳遞給對應處理器。比如,在windows上,處理器發起一個異步IO操作,再由事件分離器等待IOCompletion事件。典型的異步模式實作,都建立在作業系統支援異步API的基礎之上,我們将這種實作稱為“系統級”異步或“真”異步,因為應用程式完全依賴作業系統執行真正的IO工作。

舉個例子,将有助于了解Reactor與Proactor二者的差異,以讀操作為例(類操作類似)。

在Reactor中實作讀:

- 注冊讀就緒事件和相應的事件處理器

- 事件分離器等待事件

- 事件到來,激活分離器,分離器調用事件對應的處理器。

- 事件處理器完成實際的讀操作,處理讀到的資料,注冊新的事件,然後返還控制權。

在Proactor中實作讀:

- 處理器發起異步讀操作(注意:作業系統必須支援異步IO)。在這種情況下,處理器無視IO就緒事件,它關注的是完成事件。

- 事件分離器等待操作完成事件

- 在分離器等待過程中,作業系統利用并行的核心線程執行實際的讀操作,并将結果資料存入使用者自定義緩沖區,最後通知事件分離器讀操作完成。

- 事件分離器呼喚處理器。

- 事件處理器處理使用者自定義緩沖區中的資料,然後啟動一個新的異步操作,并将控制權傳回事件分離器。

可以看出,兩個模式的相同點,都是對某個IO事件的事件通知(即告訴某個子產品,這個IO操作可以進行或已經完成)。在結構上,兩者也有相同點:demultiplexor負責送出IO操作(異步)、查詢裝置是否可操作(同步),然後當條件滿足時,就回調handler;不同點在于,異步情況下(Proactor),當回調handler時,表示IO操作已經完成;同步情況下(Reactor),回調handler時,表示IO裝置可以進行某個操作(can read or can write)。

2、通俗了解

使用Proactor架構和Reactor架構都可以極大的簡化網絡應用的開發,但它們的重點卻不同。

Reactor架構中使用者定義的操作是在實際操作之前調用的。比如你定義了操作是要向一個SOCKET寫資料,那麼當該SOCKET可以接收資料的時候,你的操作就會被調用;而Proactor架構中使用者定義的操作是在實際操作之後調用的。比如你定義了一個操作要顯示從SOCKET中讀入的資料,那麼當讀操作完成以後,你的操作才會被調用。

Proactor和Reactor都是并發程式設計中的設計模式。在我看來,他們都是用于派發/分離IO操作事件的。這裡所謂的IO事件也就是諸如read/write的IO操作。"派發/分離"就是将單獨的IO事件通知到上層子產品。兩個模式不同的地方在于,Proactor用于異步IO,而Reactor用于同步IO。

平時接觸的開源産品如Redis、ACE,事件模型都使用的Reactor模式;而同樣做事件處理的Proactor,由于作業系統的原因,相關的開源産品也少;這裡學習下其模型結構,重點對比下兩者的異同點;

3、IO設計模式:Reactor和Proactor對比

平時接觸的開源産品如Redis、ACE,事件模型都使用的Reactor模式;而同樣做事件處理的Proactor,由于作業系統的原因,相關的開源産品也少;這裡學習下其模型結構,重點對比下兩者的異同點;

反應器Reactor

Reactor模式結構

Reactor和Proactor網絡程式設計模型1、标準定義2、通俗了解3、IO設計模式:Reactor和Proactor對比

Reactor包含如下角色:

  • Handle 句柄;用來辨別socket連接配接或是打開檔案;
  • Synchronous Event Demultiplexer:同步事件多路分解器:由作業系統核心實作的一個函數;用于阻塞等待發生在句柄集合上的一個或多個事件;(如select/epoll;)
  • Event Handler:事件處理接口
  • Concrete Event HandlerA:實作應用程式所提供的特定事件處理邏輯;
  • Reactor:反應器,定義一個接口,實作以下功能: 

    1)供應用程式注冊和删除關注的事件句柄; 

    2)運作事件循環; 

    3)有就緒事件到來時,分發事件到之前注冊的回調函數上處理;

“反應”器名字中”反應“的由來: 

“反應”即“倒置”,“控制逆轉”,具體事件處理程式不調用反應器,而是由反應器配置設定一個具體事件處理程式,具體事件處理程式對某個指定的事件發生做出反應;這種控制逆轉又稱為“好萊塢法則”(不要調用我,讓我來調用你)

業務流程及時序圖

Reactor和Proactor網絡程式設計模型1、标準定義2、通俗了解3、IO設計模式:Reactor和Proactor對比
  1. 應用啟動,将關注的事件handle注冊到Reactor中;
  2. 調用Reactor,進入無限事件循環,等待注冊的事件到來;
  3. 事件到來,select傳回,Reactor将事件分發到之前注冊的回調函數中處理;

主動器Proactor

Proactor模式結構

Reactor和Proactor網絡程式設計模型1、标準定義2、通俗了解3、IO設計模式:Reactor和Proactor對比

Proactor主動器模式包含如下角色

  • Handle 句柄;用來辨別socket連接配接或是打開檔案;
  • Asynchronous Operation Processor:異步操作處理器;負責執行異步操作,一般由作業系統核心實作;
  • Asynchronous Operation:異步操作
  • Completion Event Queue:完成事件隊列;異步操作完成的結果放到隊列中等待後續使用
  • Proactor:主動器;為應用程式程序提供事件循環;從完成事件隊列中取出異步操作的結果,分發調用相應的後續處理邏輯;
  • Completion Handler:完成事件接口;一般是由回調函數組成的接口;
  • Concrete Completion Handler:完成事件處理邏輯;實作接口定義特定的應用處理邏輯;

業務流程及時序圖

Reactor和Proactor網絡程式設計模型1、标準定義2、通俗了解3、IO設計模式:Reactor和Proactor對比
  1. 應用程式啟動,調用異步操作處理器提供的異步操作接口函數,調用之後應用程式和異步操作處理就獨立運作;應用程式可以調用新的異步操作,而其它操作可以并發進行;
  2. 應用程式啟動Proactor主動器,進行無限的事件循環,等待完成事件到來;
  3. 異步操作處理器執行異步操作,完成後将結果放入到完成事件隊列;
  4. 主動器從完成事件隊列中取出結果,分發到相應的完成事件回調函數處理邏輯中;

對比兩者的差別

主動和被動

以主動寫為例: 

Reactor将handle放到select(),等待可寫就緒,然後調用write()寫入資料;寫完處理後續邏輯; 

Proactor調用aoi_write後立刻傳回,由核心負責寫操作,寫完後調用相應的回調函數處理後續邏輯;

可以看出,Reactor被動的等待訓示事件的到來并做出反應;它有一個等待的過程,做什麼都要先放入到監聽事件集合中等待handler可用時再進行操作; 

Proactor直接調用異步讀寫操作,調用完後立刻傳回;

實作

Reactor實作了一個被動的事件分離和分發模型,服務等待請求事件的到來,再通過不受間斷的同步處理事件,進而做出反應;

Proactor實作了一個主動的事件分離和分發模型;這種設計允許多個任務并發的執行,進而提高吞吐量;并可執行耗時長的任務(各個任務間互不影響)

優點

Reactor實作相對簡單,對于耗時短的處理場景處理高效; 

作業系統可以在多個事件源上等待,并且避免了多線程程式設計相關的性能開銷和程式設計複雜性; 

事件的串行化對應用是透明的,可以順序的同步執行而不需要加鎖; 

事務分離:将與應用無關的多路分解和配置設定機制和與應用相關的回調函數分離開來,

Proactor性能更高,能夠處理耗時長的并發場景;

缺點

Reactor處理耗時長的操作會造成事件分發的阻塞,影響到後續事件的處理;

Proactor實作邏輯複雜;依賴作業系統對異步的支援,目前實作了純異步操作的作業系統少,實作優秀的如windows IOCP,但由于其windows系統用于伺服器的局限性,目前應用範圍較小;而Unix/Linux系統對純異步的支援有限,應用事件驅動的主流還是通過select/epoll來實作;

适用場景

Reactor:同時接收多個服務請求,并且依次同步的處理它們的事件驅動程式; 

Proactor:異步接收和同時處理多個服務請求的事件驅動程式;

類圖和序列圖的源檔案提供下載下傳,詳見Github《圖說設計模式》的EA文檔:

https://github.com/me115/design_patterns

繼續閱讀