libevent之eventop
在之前博文libevent之Reactor模式中,我们知道Reactor模式中一个重要的组件就是事件多路分发机制(event demultiplexer)。而在libevent中,对事件多路分发机制的支持依赖于操作系统支持的多路复用机制(select、poll、epoll等)。
eventop
libevent定义了一个顶层的结构体eventop(event option),来抽象不同操作系统支持的多路复用机制:
// <event_internal.h>
1 /** Structure to define the backend of a given event_base. */
struct eventop {
/** The name of this backend. */
const char *name;
/** Function to set up an event_base to use this backend. It should
* create a new structure holding whatever information is needed to
* run the backend, and return it. The returned pointer will get
* stored by event_init into the event_base.evbase field. On failure,
* this function should return NULL. */
void *(*init)(struct event_base *);
/** Enable reading/writing on a given fd or signal. 'events' will be
* the events that we're trying to enable: one or more of EV_READ,
* EV_WRITE, EV_SIGNAL, and EV_ET. 'old' will be those events that
* were enabled on this fd previously. 'fdinfo' will be a structure
* associated with the fd by the evmap; its size is defined by the
* fdinfo field below. It will be set to 0 the first time the fd is
* added. The function should return 0 on success and -1 on error.
*/
int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
/** As "add", except 'events' contains the events we mean to disable. */
int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);
/** Function to implement the core of an event loop. It must see which
added events are ready, and cause event_active to be called for each
active event (usually via event_io_active or such). It should
return 0 on success and -1 on error.
*/
int (*dispatch)(struct event_base *, struct timeval *);
/** Function to clean up and free our data from the event_base. */
void (*dealloc)(struct event_base *);
/** Flag: set if we need to reinitialize the event base after we fork.
*/
int need_reinit;
/** Bit-array of supported event_method_features that this backend can
* provide. */
enum event_method_feature features;
/** Length of the extra information we should record for each fd that
has one or more active events. This information is recorded
as part of the evmap entry for each fd, and passed as an argument
to the add and del functions above.
*/
size_t fdinfo_len;
};
可以看到,该结构体已经声明(非定义)了多路分发机制常备的Reactor初始化、事件添加、事件移除、事件分发及Reactor清理函数,而且均以函数指针的方式定义,便于复用。
如epoll对该结构体的一个复用:
static void *epoll_init(struct event_base *);
static int epoll_dispatch(struct event_base *, struct timeval *);
static void epoll_dealloc(struct event_base *); static const struct eventop epollops_changelist = {
"epoll (with changelist)",
epoll_init,
event_changelist_add,
event_changelist_del,
epoll_dispatch,
epoll_dealloc,
, /* need reinit */
EV_FEATURE_ET|EV_FEATURE_O1,
EVENT_CHANGELIST_FDINFO_SIZE
};
实际调用的多路复用机制
libevent用了一个数组来存储其所支持的多路复用机制:
// <event.c>
/* Array of backends in order of preference. */
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
};
通过这个程序,我们可以知道libevent是通过宏定义来确定当前操作系统是否支持某中多路复用机制,并且按顺序选择系统支持的机制。
另外,我们如果想知道程序当前所支持的多路复用机制,我们可以调用函数event_get_supported_methods:
// <event.c>
const char **
event_get_supported_methods(void)
{
static const char **methods = NULL;
const struct eventop **method;
const char **tmp;
int i = , k; /* count all methods */
for (method = &eventops[]; *method != NULL; ++method) {
++i;
} /* allocate one more than we need for the NULL pointer */
tmp = mm_calloc((i + ), sizeof(char *));
if (tmp == NULL)
return (NULL); /* populate the array with the supported methods */
for (k = , i = ; eventops[k] != NULL; ++k) {
tmp[i++] = eventops[k]->name;
}
tmp[i] = NULL; if (methods != NULL)
mm_free((char**)methods); methods = tmp; return (methods);
}
而要想知道程序实际调用的是哪一种多路复用机制,我们可以调用函数event_get_method得到:
// <event.c>
const char *
event_get_method(void)
{
return (current_base->evsel->name);
}
libevent之eventop的更多相关文章
- libevent源码分析:eventop
eventop:定义了event_base使用的后端IO复用的一个统一接口 /** Structure to define the backend of a given event_base. */ ...
- Libevent的IO复用技术和定时事件原理
Libevent 是一个用C语言编写的.轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大:源代码相当精炼.易 ...
- Libevent初探
Libevent 是一个用C语言编写的.轻量级的开源高性能网络库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大:源代码相当精炼.易 ...
- libevent源码分析:time-test例子
time-test例子是libevent自带的一个例子,通过libevent提供的定时事件来实现,间隔固定时间打印的功能. /* * gcc -g -o time-test time-test.c - ...
- 【转】libevent源码分析
libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...
- libevent源码分析(一)
分析libevent的源代码,我的想法的是先分析各种结构体,struct event_base.struct event,然后是event_base_new函数.event_new函数.event_a ...
- libevent源码深度剖析
原文地址: http://blog.csdn.net/sparkliang/article/details/4957667 第一章 1,前言 Libevent是一个轻量级的开源高性能网络库,使用者众多 ...
- libevent+bufferevent总结
libevent+bufferevent总结 1 学习参考网址 libevent学习网址:http://blog.csdn.net/feitianxuxue/article/details/93725 ...
- 使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作. 有许多解决方案,但事件驱动也被广泛应用到网络编程中.并大规模部署在高 ...
随机推荐
- 不可错过的Node.js框架
前言 Node.js是由Ryan Dahl于2009年创建的.它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的. ...
- Ruby 连接MySQL数据库
使用Ruby连接数据库的过程还真的是坎坷,于是写点文字记录一下. 简介 Ruby简介 RubyGems简介 包管理之道 比较著名的包管理举例 细说gem 常用的命令 准备 驱动下载 dbi mysql ...
- RE模块错误已解决.
下面这个错误是由于在正则[...]的内部,减号'-'是一个有特殊含义的字符(代表字符范围) 所以如果需要在[...]内匹配减号'-',需要用反斜杠'\'转义. >>> import ...
- Redis 学习笔记4: Redis 3.2.1 集群搭建
在CenOS 6.7 linux环境下搭建Redis 集群环境 1.下载最新的Redis版本 本人下载的Redis版本是3.2.1版本,下载之后,解压,编译(make): 具体操作可以参考我的博文:R ...
- [Mysql]Innodb 独立表空间和共享表空间
innodb有2中表空间方式: 共享表空间 和 独立表空间 查询数据的设置: show variables like '%per_table'; 默认是共享表空间,独立表空间在配置文件中添加 inno ...
- pipeline(管道)设计模式
- SQLite 语法(http://www.w3cschool.cc/sqlite/sqlite-syntax.html)
SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和准则.本教程列出了所有基本的 SQLite 语法,向您提供了一个 SQLite 快速入门. 大小写敏感性 有个重要的点值得注意,SQL ...
- Impala中的代码生成技术
Cloudera Impala是一种为Hadoop生态系统打造的开源MPP(massive parallel processing)数据库,它主要为分析型查询负载而设计,而非OLTP.Impala能最 ...
- android自定义view实现progressbar的效果
一键清理是很多Launcher都会带有的功能,其效果也比较美观.实现方式也许有很多中,其中常见的是使用图片drawable来完成的,具体可以参考这篇文章:模仿实现360桌面水晶球式的一键清理特效.本文 ...
- 财务模块多组织,GL, SLA, SOB, COA, BSV, CCID, LE 概念的简单介绍
GL= General Ledger 指的是Oracle 的总帐系统. application_id = 101. 在uk似乎居然还有不同的解释(In the UK, it was refer ...