Libevent中的多路分发器有两个用途:1)I/0事件的触发;2)相应函数对应的超时功能,可以用来作为定时器功能。
在不同的os环境,有多种分发器可以使用,在新建Reactor事件实例时,按顺序选择第一个可以使用且初始化成功的分发器:
Event.c:
/* In order of preference */
static const struct eventop *eventops[] = {
#ifdef HAVE_EVENT_PORTS
&evportops,
#endif
#ifdef HAVE_WORKING_KQUEUE
&kqops,
#endif
#ifdef HAVE_EPOLL
&epollops,
#endif
#ifdef HAVE_DEVPOLL
&devpollops,
#endif
#ifdef HAVE_POLL
&pollops,
#endif
#ifdef HAVE_SELECT
&selectops,
#endif
#ifdef WIN32
&win32ops,
#endif
NULL
};
struct event_base * event_base_new(void)
{
......
for (i = 0; eventops[i] && !base->evbase; i++) {
base->evsel = eventops[i];
base->evbase = base->evsel->init(base);
}
......
}
每个分发器实现如下函数接口:
struct eventop {
const char *name;
void *(*init)(struct event_base *);
int (*add)(void *, struct event *); /*增加事件*/
int (*del)(void *, struct event *);
int (*dispatch)(struct event_base *, void *, struct timeval *);
void (*dealloc)(struct event_base *, void *);
/* set if we need to reinitialize the event base */
int need_reinit;
};
linux系统一般使用epoll,epoll_wait实现最后的事件分发:
#include <sys/epoll.h>
/***********************************************************************
epfd :epoll文件描述符
events :接口的返回参数,一般都是一个数组,数组长度大于等于maxevents。
maxevents:期望捕获的事件的个数。
timeout :超时时间(>=0),单位是毫秒ms,-1表示阻塞,0表示不阻塞。
************************************************************************/
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);