码迷,mamicode.com
首页 > 其他好文 > 详细

典型服务器模型

时间:2015-04-23 23:26:02      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

ibevent:

reactor反应堆模型:

技术分享

 

关键部分:

1) 事件源
Linux上是文件描述符,Windows上就是Socket或者Handle了,这里统一称为“句柄集”;程序在指定的句柄上注册关心的事件,比如I/O事件。

2) event demultiplexer——事件多路收集和分发机制(其实就是epoll等,直接运用在reactor中)
由操作系统提供的I/O多路复用机制,比如select和epoll。
程序首先将其关心的句柄(事件源)及其事件注册到event demultiplexer上;
当有事件到达时,event demultiplexer会发出通知“在已经注册的句柄集中,一个或多个句柄的事件已经就绪”;
程序收到通知后,就可以在非阻塞的情况下对事件进行处理了。
对应到libevent中,依然是select、poll、epoll等,但是libevent使用结构体eventop进行了封装,以统一的接口来支持这些I/O多路复用机制,达到了对外隐藏底层系统机制的目的。

3) Reactor——反应器
Reactor,是事件管理的接口,内部使用event demultiplexer注册、注销事件;并运行事件循环,当有事件进入“就绪”状态时,调用注册事件的回调函数处理事件。
对应到libevent中,就是event_base结构体。
一个典型的Reactor声明方式

技术分享
class Reactor
{
public:
    int register_handler(Event_Handler *pHandler, int event);
    int remove_handler(Event_Handler *pHandler, int event);
    void handle_events(timeval *ptv);
    // ...
};
View Code

4) Event Handler——事件处理程序,(注意,事件处理函数是一个整体,这个整体可以注册,跟事件绑定在一起,换句话说,这个事件处理函数类,声称对这个事件感兴趣(所谓的事件,就是读写事情等等)
    事件处理程序提供了一组接口,每个接口对应了一种类型的事件,供Reactor在相应的事件发生时调用,执行相应的事件处理。通常它会绑定一个有效的句柄。
对应到libevent中,就是event结构体。
下面是两种典型的Event Handler类声明方式,二者互有优缺点。

技术分享
class Event_Handler
{
public:
    virtual void handle_read() = 0;
    virtual void handle_write() = 0;
    virtual void handle_timeout() = 0;
    virtual void handle_close() = 0;
    virtual HANDLE get_handle() = 0;
    // ...
};
class Event_Handler
{
public:
    // events maybe read/write/timeout/close .etc
    virtual void handle_events(int events) = 0;
    virtual HANDLE get_handle() = 0;
    // ...
};
View Code

然后就在reactor中不停的循环wait_epoll,这利用demultiplexer中函数进行,同时reactor的hanle_events是(当事件源就绪的时候,回调之前注册过的时间处理函数)通过转接demultiplexer中的函数,由于,得到的就绪的fd,可以得使他就绪的事件,根据handle和事件处理函数之间的关系,通过map存储,这样就可以得到注册的事件处理函数,然后又根据事件类型(写还是读),调用事件处理类中的对应函数

每个事件处理类,对应一个handle,但是一个同样的handle可以跟多个事件处理类对应(不同时刻)。这个handle有aceept生成。

int ReactorImplementation::RegisterHandler(EventHandler * handler, event_t evt)    //参数是事件处理类和事件,但是通过事件处理类中的GetHandle()函数得到事件处理类对应的handle事件源。然后进行handle和事件处理类之间的对应关系的     {                                                                                                                       // map
handle_t handle = handler->GetHandle();
std::map<handle_t, EventHandler *>::iterator it = m_handlers.find(handle);
if (it == m_handlers.end())
{
m_handlers[handle] = handler;
}
return m_demultiplexer->RequestEvent(handle, evt);
}

map<handle_t, EventHandler *>  m_handlers;//可知道socket描述符和事件处理类有一对一的关系。。wait_epoll得到就绪的fd还有引发fd就绪的事件,就可以回调当初与事件绑定的事件处理类(回调)

 

每个fd都有相应事件,如果对应fd上面的事件就绪,就返回fd,又因为注册的时候,事件是跟事件处理类对应的,事件处理类声称对事件感兴趣。所以可以根据,fd找到对应的就绪事件,然后回调事件处理类。注册事件的函数的参数是fd类型和事件处理类类型。

典型服务器模型

标签:

原文地址:http://www.cnblogs.com/kkshaq/p/4451939.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!