解析libevent不同操作系统下如何选择I/O多路复用机制

7 篇文章 0 订阅
解析libevent 1.4.14 版本如何实现不同操作系统下配置使用I/O demultiplex机制:
一、定义
  • libevent在编译阶段选择系统的I/O demultiplex机制,而不支持在运行阶段根据配置选择。
  • Libevent支持多种I/O多路复用技术的关键就在于结构体eventop,它的成员是一系列的函数指针, 定义在event-internal.h文件中:
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;
};
在libevent中,每种I/O demultiplex机制的实现都必须提供这五个函数接口,来完成自身的初始化、销毁释放;对事件的注册、注销和分发。 
  • 通过宏定义在编译的时候选择相应的I/O多路复用对象,同时用extern申明要取的对象是在别处定义的。 event.c 文件中:
#ifdef HAVE_EVENT_PORTS
extern const struct eventop evportops;
#endif
#ifdef HAVE_SELECT
extern const struct eventop selectops;
#endif
#ifdef HAVE_POLL
extern const struct eventop pollops;
#endif
#ifdef HAVE_EPOLL
extern const struct eventop epollops;
#endif
#ifdef HAVE_WORKING_KQUEUE
extern const struct eventop kqops;
#endif
#ifdef HAVE_DEVPOLL
extern const struct eventop devpollops;
#endif
#ifdef WIN32
extern const struct eventop win32ops;
#endif

通过宏定义选择系统的I/O多路复用机制存储在一个全局静态数组eventops中,数组内容根据优先级顺序声明如下:
/* 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
};

二、实现
  • 在每一个(epoll、poll、dev/poll、select和kqueue)I/O多路复用机制的实现文件里定义了上面申明的 eventop对象。举例epoll机制在epoll.c文件:
const struct eventop epollops = {
 "epoll",
 epoll_init,
 epoll_add,
 epoll_del,
 epoll_dispatch,
 epoll_dealloc,
 1 /* need reinit */
};

变量epollops中的函数指针具体声明如下,注意到其返回值和参数都和eventop中的定义严格一致,这是函数指针的语法限制。
static void *epoll_init (struct event_base *);
static int epoll_add (void *, struct event *);
static int epoll_del (void *, struct event *);
static int epoll_dispatch(struct event_base *, void *, struct timeval *);
static void epoll_dealloc (struct event_base *, void *);

三、调用
  • 在用户使用编译好的libevent库时,会调用event_init()初始化event_base框架。这时就会去 eventops[i] 里取优先级最高的 I/O demultiplex机制赋给框架使用。这段代码在文件event.c函数event_base_new()中:
base->evbase = NULL;
for (i = 0; eventops[i] && !base->evbase; i++) {
base->evsel = eventops[i];
base->evbase = base->evsel->init(base);
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值