libevent的設計是一個典型的Reactor模型,理解Reactor模型是理解libevent的基石,所以本節主要介紹典型的事件驅動設計模式---Reactor模式react
The Reactor design pattern handles service requests that are delivered concurrently to an application by one or more clients.git
在reactor.pdf第一句話就直接說到Reactor 設計模式能夠爲一個應用同時處理一個或者多個客戶端請求服務github
Reactor Bing 中文翻譯爲 "反應堆,反應器",是一種事件驅動機制。與普通函數調用的不一樣之處在於:應用程序不是主動的調用某個API完成處理,而是偏偏相反,Reactor逆置了事件處理流程,應用程序須要提供相應的接口並註冊到Reactor上,若是相應的事件發生,Reactor將主動調用應用程序註冊的接口,這些接口又稱爲"callback function"(回調函數).編程
在使用libevent時,須要向libevent框架註冊相應的事件和會調函數,當註冊的相應事件發生時,libevent會調用回調函數處理相應的時間(I/O讀寫,定時器,信號)設計模式
用"好萊塢原則"來形容Reactor再合適不過了: 不要打電話給咱們,咱們會打電話通知你。數組
在Reactor模式中,有5個關鍵參與者。服務器
在上圖中,能夠看到Rector管理器(dispatcher)是Reactor模式中最爲關鍵的角色,它是該模式最終向用戶提供接口的類。用戶能夠向Reactor中註冊event handler,而後Reactor在react的時候,發現用戶註冊的fd有事件發生,就會調用用戶的事件處理函數。下面是一個典型的reactor聲明方式:網絡
class Reactor { public: //構造函數 Reactor(); //析構函數 ~Reactor(); //向reactor中註冊關注事件evt的handler(可重入) //@param handler 要註冊的事件處理器 //@param evt 要關注的事件 //@retval 0 註冊成功 //@retval -1 註冊出錯 int RegisterHandler(EventHandler *handler, event_t evt); //從reactor中移除handler //param handler 要移除的事件處理器 //retval 0 移除成功 //retval -1 移除出錯 int RemoveHandler(EventHandler *handler); //處理事件,回調註冊的handler中相應的事件處理函數 //@param timeout 超時事件(毫秒) void HandlerEvents(int timeout = 0); private: ReactorImplementation *m_reactor_impl; //reactor的實現類 }
SynchrousEventDemultiplexer也是Reactor中一個比較重要的角色,它是Reactor用來檢測用戶註冊的fd上發生的事件的利器,經過Reactor得知了那些fd上發生了什麼樣的事件,而後以這些爲依據,來多路分發事件,回調用戶事件處理函數。下面是一個簡單的設計:多線程
class EventDemultiplexer { public: /// 獲取有事件發生的全部句柄以及所發生的事件 /// @param events 獲取的事件 /// @param timeout 超時時間 /// @retval 0 沒有發生事件的句柄(超時) /// @retval 大於0 發生事件的句柄個數 /// @retval 小於0 發生錯誤 virtual int WaitEvents(std::map<handle_t , event_t> * events, int timeout = 0) = 0; /// 設置句柄handle關注evt事件 /// @retval 0 設置成功 /// @retval 小於0 設置出錯 virtual int RequestEvent(handle_t handle, event_t evt) = 0; /// 撤銷句柄handle對事件evt的關注 /// @retval 0 撤銷成功 /// @retval 小於0 撤銷出錯 virtual int UnrequestEvent(handle_t handle, event_t evt) = 0; };
Event Handler事件處理程序提供一組接口,每一個接口對應了一種類型的事件,供Reactr在相應的事件發生時調用,執行相應的事件處理。一般它會綁定一個有效的句柄。對應到libevent中,就是event結構體。下面是典型的Event Handler類兩種聲明方式。app
class Event_Handler { public: //處理讀事件的回調函數 virtual void handle_read() = 0; //處理寫事件的回調函數 virtual void handle_write() = 0; //處理超時的回調函數 virtual void handle_timeout() = 0; //關閉對應的handle句柄 virtual void handle_close() = 0; //獲取該handler所對應的句柄 virtual HANDLE get_handle() = 0; }; ________________________________________________________________________________ class Event_Handler { public: //event maybe read/write/timeout/close .etc virtual void hand_events(int events) = 0; virtual HANDLE get_handle() = 0; }
ConcreteEventHandler具體事件處理器是EventHanler的子類,EventHandler是Reactor所用來規定接口的基類,用戶本身的事件處理器都必須從EventHandler繼承。
下面這幅圖展現了應用程序在參與在Reactor模式下的協做交互
Reactor模式是編寫高性能網絡服務器的必備技術之一,它具備以下優勢:
免責聲明:本文部份內容整理參考來自互聯網,本着分享學習的目的,並沒有商用,若有侵犯之處能夠與我聯繫並刪除。
參考來源:
若是以爲有用,能夠Github上star並鼓勵我,或者Pull Reauest 修正