libevent札记 - C语言也能实现多态
2017-08-22 13:46
330 查看
0.前言
在C++中,提供了虚函数来实现多态,libevent是用C 语言写的,在libevent中,这是通过函数指针来实现的。1. 从IO复用封装看多态的实现
1.1 多态的关键
Libevent能够支持多种I/O多路复用技术来实现对事件的处理,关键在于结构体eventop,这个结构体的成员是一系列的函数指针, 定义在event-internal.h文件中:struct eventop { const char *name; void *(*init)(struct event_base *); int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo); int (*dispatch)(struct event_base *, struct timeval *); void (*dealloc)(struct event_base *); int need_reinit; enum event_method_feature features; size_t fdinfo_len; };
在 libevent 中,每种 I/O demultiplex 机制的实现都必须提供这五个函数接口,来完成自
身的初始化、销毁释放;对事件的注册、注销和分发。
比如对于 epoll, libevent 实现了 5 个对应的接口函数,并在初始化时并将 eventop 的5个函数指针指向这 5 个函数,那么程序就可以使用 epoll 作为 I/O demultiplex 机制了。
1.2 根据系统环境选择IO复用机制的优先级
全局静态数组 eventops中,数组内容根据优先级顺序声明:#ifdef _EVENT_HAVE_POLL extern const struct eventop pollops; #endif #ifdef _EVENT_HAVE_EPOLL extern const struct eventop epollops; #endif /* In order of preference */ static const struct eventop *eventops[] = { #ifdef _EVENT_HAVE_WORKING_KQUEUE &kqops, #endif #ifdef _EVENT_HAVE_EPOLL &epollops, #endif #ifdef _EVENT_HAVE_POLL &pollops, #endif #ifdef WIN32 &win32ops, #endif NULL };
然后 libevent 根据系统配置和编译选项决定使用哪一种 I/O demultiplex 机制,函数 event_base_new_with_config()中:
base->evbase = NULL; for (i = 0; eventops[i] && !base->evbase; i++) { base->evsel = eventops[i]; base->evbase = base->evsel->init(base); }
以 Linux 下面的 epoll 为例,实现在源文件 epoll.c 中, eventops 对象 epollops 定义如下:
const struct eventop epollops = { "epoll", epoll_init, epoll_add, epoll_del, epoll_dispatch, epoll_dealloc, 1, /* need reinit */ EV_FEATURE_ET|EV_FEATURE_O1, 0 };
变量 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 *);
那么如果选择的是 epoll,那么调用结构体 eventop 的 init 和 dispatch 函数指针时,实际调用的函数就是 epoll 的初始化函数 epoll_init()和事件分发函数 epoll_dispatch()了;
同样的,上面 epollops 以及 epoll 的各种函数都直接定义在了 epoll.c 源文件中,对外都是不可见的。
对于 libevent 的使用者而言,完全不会知道它们的存在,对 epoll 的使用也是通过 eventop 来完成的,达到了信息隐藏的目的。
2 小节
首先是定义结构体eventop,结构体包含一系列的函数指针 –> 通过头文件根据系统环境选择相应的IO复用机制函数指针 –> 指向具体的IO复用机制函数从上面可以看出,让libevent实现多态,支持多种 I/O 复用机制的方法通过借助于函数指针实现就 OK 了。
通过对源代码的分析也可以看出, Libevent 是在编译阶段选择系统的 I/O 复用 机制的,而不支持在运行阶段根据配置再次选择。
相关文章推荐
- C语言实现封装、继承和多态
- C语言也可以“面向对象”—— C语言实现封装、继承和多态
- c语言中继承和多态的简单实现
- 软件设计本质论(Essential Design) —白话面向对象 (转注:关于c语言实现封装继承多态的一堆博文)
- C语言实现继承和多态
- C语言中的面向对象(2)-C语言的多态实现
- C语言实现C++多态------函数指针
- C语言模式实现C++继承和多态
- C语言模式实现C++继承和多态
- C语言如何实现继承和多态
- C语言的多态实现
- C语言是怎样实现封装、继承、多态的?
- C语言实现封装、继承和多态
- C语言实现多态
- C语言如何实现继承和多态,写的very nice
- Python源码 -- C语言实现面向对象编程(基类&派生类&多态)
- C语言模拟实现C++中的继承和多态
- C语言实现C++多态
- C语言中的多态实现
- C语言实现继承和多态