现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Reactor模式介绍

2018-03-11 22:33 工业·编程 ⁄ 共 1497字 ⁄ 字号 暂无评论

Reactor模式是编写高性能网络服务器的必备技术之一,它具有如下的优点

  • 响应快,不必为单个同步时间所阻塞,虽然 Reactor 本身依然是同步的;
  • 编程相对简单,可以最大程度的避免复杂的多线程及同步问题,并且避免了多线程/
  • 进程的切换开销;
  • 可扩展性,可以方便的通过增加 Reactor 实例个数来充分利用 CPU 资源;
  • 可复用性, reactor 框架本身与具体事件处理逻辑无关,具有很高的复用性

下图描述了Reactor模式的框架,主要包括:事件源、框架部分(Reactor)、事件多路分发机制(event demultiplexing)、事件处理程序(event handler)。

Reactor模式介绍

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

在libevent中有三种类型的事件:定时器事件(time event)、信号事件(signal event)和I/O事件。

2、事件多路分发机制(event demultiplexing)

需要使用底层提供的多路复用机制,如evport, select , poll, epoll, kqueue, devpoll. 用户进程首先在event demultiplexing上注册事件,采用合适的多路复用机制检测事件,当事件发生时,event demultiplexing发出通知“在已经注册的事件集中,一个或多个事件已经就绪“,程序收到通知后对事件进行处理。

1)libevent中对多路复用机制进行了封装,使得根据操作系统,可以选择最高效的IO机制。

static const struct eventop *eventops[] = {

#ifdef _EVENT_HAVE_EVENT_PORTS

        &evportops,

#endif

#ifdef _EVENT_HAVE_WORKING_KQUEUE

        &kqops,

#endif

#ifdef _EVENT_HAVE_EPOLL

        &epollops,

#endif

#ifdef _EVENT_HAVE_DEVPOLL

        &devpollops,

#endif

#ifdef _EVENT_HAVE_POLL

        &pollops,

#endif

#ifdef _EVENT_HAVE_SELECT

        &selectops,

#endif

#ifdef WIN32

        &win32ops,

#endif

        NULL

};

2)事件注册:

首先,对event进行初始化,并将event与event_base(可以理解为事件库)关联起来,如下:

event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg)

其中cb表示事件处理函数,也即回调函数,需要用户实现。

然后,将事件添加到事件库,此时event的状态为pending:

int event_add(struct event *ev, const struct timeval *tv);

3)事件触发:

在事件加入event_base后,选择合适的多路复用机制遍历事件队列,将状态为激活(active)的事件插入到激活队列中,从高到低优先级遍历激活event优先级数组。对于激活的event,调用event_queue_remove将之从激活队列中删除掉。然后再对这个event调用其回调函数。

整个Reactor的流程如下:

Reactor模式介绍

给我留言

留言无头像?