libevent 的Reactor模型
libevent的设计是一个典型的Reactor模型,理解Reactor模型是理解libevent的基石,因此本节主要介绍典型的事件驱动设计模式---Reactor模式
在reactor.pdf第一句话就直接说到Reactor 设计模式可以为一个应用同时处理一个或者多个客户端请求服务 Reactor的事件处理机制Reactor Bing 中文翻译为 "反应堆,反应器",是一种事件驱动机制。与普通函数调用的不同之处在于:应用程序不是主动的调用某个API完成处理,而是恰恰相反,Reactor逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,如果相应的事件发生,Reactor将主动调用应用程序注册的接口,这些接口又称为"callback function"(回调函数). 在使用libevent时,需要向libevent框架注册相应的事件和会调函数,当注册的相应事件发生时,libevent会调用回调函数处理相应的时间(I/O读写,定时器,信号) 用"好莱坞原则"来形容Reactor再合适不过了: 不要打电话给我们,我们会打电话通知你。 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类两种声明方式。 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模式下的协作交互 Reactor模式的优点Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下优点:
免责声明:本文部分内容整理参考来自互联网,本着分享学习的目的,并无商用,如有侵犯之处可以与我联系并删除。 参考来源:
如果觉得有用,可以Github上star并鼓励我,或者Pull Reauest 修正 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |