反應堆模式


一、概念

  1、定義

  反應堆模式是一種對象行為類的設計模式,對同步事件分揀和派發。它是處理並發I/O比較常見的一種模式,用於同步I/O。

  其中心思想是將所有要處理的I/O事件注冊到一個中心I/O多路復用器上,同時主線程阻塞在多路復用器上;一旦有I/O事件到來或者是准備就緒,多路復用器返回並將相應的I/O事件分發到對應的處理器中。

  2、Reactor事件處理機制

    Reactor是一種事件驅動機制,和普通函數的不同之處在於:應用程序不是主動的調用某個API完成處理,Reactor逆置了事件處理流程,應用程序需要提供相應的接口並注冊到Reactor上,如果相應的時間發生,Reactor將主動調用應用程序注冊的接口(這些接口又被稱為"回調函數")。下面是事件驅動機制的模型圖:

  

  事件驅動(回調)就是應用業務向一個中間人注冊一個回調(event handler),當I/O就緒后,就向這個中間人產生一個事件,並通知此handler進行處理。這個中間人是由一個不斷等待和循環的單獨線程來承擔,它接受所有的handler的注冊,並負責向操作系統查詢IO是否就緒在就緒后就調用指定的handler進行處理。這個中間人的名字就就叫做Reactor。

  3、優點

  Reactor模式是編寫高性能網絡服務器的必備技術,主要有以下優點:

  • 相應快,不必為單個同步事件所阻塞,雖然Reactor本身也是同步的
  • 避免了多線程/進程的的切換開銷
  • 可擴展性,可以方便的通過增加Reactor實例個數來充分利用CPU資源

二、反應堆模式組成

  

  

  1、Handler事件源

  Handler代表操作系統管理的資源,包括:網絡連接、打開的文件、同步對象等等。事件可以來自外部,如客戶端的連接請求、數據等,也可以來自內部,如定時器事件。

  2、Synchronous event demultiplexer同步事件分離器(事件多路分發機制)

  由操作系統提供的I/O多路復用機制,例如select和epoll,程序首先將其關心的句柄(即事件源)及其事件注冊到event demultiplexer上,當有事件到達時,event demultiplexer會發出通知“在已經注冊的句柄集中,一個或者多個句柄的事件已經就緒”;程序收到通知后,就可以在非阻塞的情況下對事件進行處理了。

  3、event Handler事件處理接口

  一個或多個模板函數組成的接口,描述了和應用程序相關的對某個事件的操作

  4、concrete event Handler具體的事件處理器

  事件處理接口的實現,實現了應用程序提供的某個服務

  5、Reactor反應器

  定義了一些接口,用於應用程序控制事件調度,以及應用程序注冊、刪除事件處理器和相關的描述符,是事件處理器的調度核心。Reactor管理器使用同步事件分離器來等待事件的發生。一旦事件發生,Reactor管理器先是分離每個事件,然后調度事件處理器,最后調用相關的模 板函數來處理這個事件。

三、NIO中的Reactor模式

  NIO中Reactor的核心是Selector。下面是一個簡單的示例:

public class Reactor implements Runnable
{
    Selector selector;
    public Reactor() throws IOException
    {
        selector = Selector.open();
    }
    public void run()
    {
        try
        {
            while (!Thread.interrupted())
            {
                // 循環,等待事件
                selector.select();
                Set selected = selector.selectedKeys();
                Iterator it = selected.iterator();
                while (it.hasNext())
                    // 調用handler,處理事件
                    dispatch((SelectionKey) (it.next()));
                selected.clear();
            }
        } catch (IOException ex)
        { /* ... */
        }
    }
    void dispatch(SelectionKey k)
    {
        Runnable r = (Runnable) (k.attachment());
        if (r != null)
            r.run();
    }
}

四、參考資料

  1、http://ifeve.com/netty-reactor-4/

  2、http://www.2cto.com/kf/201504/389198.html


免責聲明!

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



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