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 修正