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模型演进变化史
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作. 有许多解决方案,但事件驱动也被广泛应用到网络编程中.并大规模部署在高 ...
随机推荐
- Tinyhttpd for Windows
TinyHTTPd forWindows 前言 TinyHTTPd是一个开源的简易学习型的HTTP服务器,项目主页在:http://tinyhttpd.sourceforge.net/,源代码下载:h ...
- 安卓热修复之AndFIX
我致力于最新的前沿安卓技术分析和使用教学,不打算将很多很深的东西,因为有多少人愿意沉下你的心境去学习难点?我一般只会简单提及.文字错漏在所难免还希望同学们喜欢 热修复介绍 热修复是什么? 如果你一个项 ...
- 《Java多线程编程核心技术》推荐
写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点 ...
- Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码
Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...
- SceneKit做一个旋转的地球效果
SceneKit可以用寥寥几行帮你完成很多OpenGL复杂的3D设置代码,下面本猫就带大家完成一个旋转的3D地球的场景. 首先需要地球表面图片,将其导入到Xcode中: 我们用SceneKit内置的几 ...
- 利用CocoaHTTPServer实现wifi局域网传输文件到iphone
背景 近日在做一个代码阅读器,其中涉及到代码文件的上传,之前看到过许多app支持局域网传文件,因此就通过查询和研究实现了此功能,我是用的框架是CocoaHTTPServer. 原理 CocoaHTTP ...
- Dynamics CRM 检测访问CRM延迟及带宽的工具
直接在浏览器中访问如下地址"http://CRMHOST/organization/tools/diagnostics/diag.aspx"(这里的CRMHOST和organiza ...
- Cocos2D实现RPG队伍菜单任意调整角色顺序的效果
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 前一篇我们实现了队伍实现拖尾效果,但是在实际游戏中我们往往需要 ...
- Blue Path(基于cocos2dx 3.0)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=498 iTunes下载:http ...
- mqtt推送介绍
方案1.使用GCM服务(Google Cloud Messaging) 简介:Google推出的云消息服务,即第二代的C2DM. 优点:Google提供的服务.原生.简单,无需实现和部署服务端. 缺点 ...