Linux -- Proactor(及其與Reactor的比較)


高並發服務器常由多線程+IO復用服務器(one event loop per thread)

兩種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中實現讀:

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

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

- 在分離器等待過程中,操作系統利用並行的內核線程執行實際的讀操作,並將結果數據存入用戶自定義緩沖區,最后通知事件分離器讀操作完成。

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

- 事件處理器處理用戶自定義緩沖區中的數據,然后啟動一個新的異步操作,並將控制權返回事件分離器。

 

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

 

使用Proactor框架和Reactor框架都可以極大的簡化網絡應用的開發,但它們的重點卻不同。Reactor框架中用戶定義的操作是在實際操作之前調用的。比如你定義了操作是要向一個SOCKET寫數據,那么當該SOCKET可以接收數據的時候,你的操作就會被調用;而Proactor框架中用戶定義的操作是在實際操作之后調用的。比如你定義了一個操作要顯示從SOCKET中讀入的數據,那么當讀操作完成以后,你的操作才會被調用。

 

Proactor和Reactor都是並發編程中的設計模式。在我看來,他們都是用於派發/分離IO操作事件的。這里所謂的IO事件也就是諸如read/write的IO操作。"派發/分離"就是將單獨的IO事件通知到上層模塊。兩個模式不同的地方在於,Proactor用於異步IO,而Reactor用於同步IO。目前應用最廣泛的是Reactor模boost::asio,ACE和Windows I/O Completion Ports 實現了Proactor 模式,應用面似乎要窄一些。

 

Proactor (論文翻譯提要)

原文: http://www.cs.wustl.edu/~schmidt/PDF/proactor.pdf

結構

1. proacitve initiator (Web server application’s main thread)

       proactive Initiator是應用中啟動異步操作的實體.proactive initiator注冊一個completion handler和一個completion dispatcher,以及一個asynchronous Operation Processor, asynchronous Operation Processor的作用是當操作完成將會通知.

2.Completion Handler(the acceptor and http handler)

       Proactor模式使用completion handler接口用來獲得異步操作完成的通知.

3.Asynchronous Operation

        異步操作,由系統API實現,如async_read,async_write,async_accept等.異步操作用來執行異步請求(如i/o或定時器.).當應用請求異步操作時,該操作不會占用應用(主)線程.因此,從整個應用的角度來看,操作表現為異步.當異步操作完成,異步操作處理器(Asynchronous         Operation Processor)將通知完成操作分發器(Completion Dispatcher)

4. Asynchronous Operation Processor(操作系統)

        異步操作由異步操作處理器(Asynchronous Operation Processor)執行完成.該組件由操作系統實現.

5. Completion Dispatcher (the Notification Queue)

        完成分發器的作用是,當異步操作完成時,把Completion handler返回給應用,即proacitve initiator

流程

1.主動啟動器(proacitve initiator)啟動操作

        為了表現為異步操作,應用在異步操作處理器中啟動操作.舉例:一個web server向OS請求通過網絡向某個特定的socket connetion發送一個文件.web server應該指定當操作完成去通知哪一個completion handler,以及當文件傳送完成后哪一個completion dispatcher去callback.

2.異步操作處理器執行操作.

       當應用在異步操作處理器上請求操作,異步操作處理器異步地執行這些操作.現代操作系統在內核中提供了異步IO.

3.異步操作處理器通知完成分發器

       當異步操作完成,異步操作處理器檢索特定的completion handler和completion dispatcher.(在第1步時指定的).然后異步操作處理器把異步操作的結果(the result of the Asynchronous Operation)和要返回的comletion handler(the Completion Handler to call back)傳遞給completion dispatcher.舉例:當文件成功地被異步發送出,異步操作處理器將會報告完成狀態(成功或失敗),同時the number of bytes written to the network connection.

4.完成分發器通知應用程序.

        舉例:例如一個異步讀操作完成后,completion handler 將被傳入一個指向newly arrived data的指針.

 

以下是POSA2中的proactor模型

http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/core/async.html

https://segmentfault.com/a/1190000002715832

多了一個proactor,completion dispatcher 改為completion event queue.

流程

  1. Initiator啟動proactor.proactor內是event loop等待完成事件的到來.
  2. 有請求到來,initiator請求asy operation processor執行異步操作.異步操作完成后,將結果返回給asy operation processor.asy operation processor將結果放入到completion event queue.
  3. Proactor進行event loop,等待completion event的到來.當queue中存在completion event,proactor獲得此完成事件並把事件結果傳遞給completion handler

 

 

以主動寫為例:

  • Reactor將handle放到select(),等待可寫就緒,然后調用write()寫入數據;寫完處理后續邏輯;
  • Proactor調用aoi_write后立刻返回,由內核負責寫操作,寫完后調用相應的回調函數處理后續邏輯;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM