[libevent]支持I/O多路复用技术

Libevent的核心是事件驱动、同步非阻塞,为了达到这一目标,必须采用系统提供的I/O多路复用技术,而这些在Windows、Linux、Unix等不同平台上却各有不同,如何能提供优雅而统一的支持方式,是首要关键的问题。

统一的关键

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机制的实现都必须提供这五个函数接口,来完成自身的初始化、销毁释放;对事件的注册、注销和分发。比如对于epoll,libevent实现了5个对应的接口函数,并在初始化时并将eventop的5个函数指针指向这5个函数,那么程序就可以使用epoll作为I/O demultiplex机制了。

设置I/O demultiplex机制

Libevent把所有支持的I/O demultiplex机制存储在一个全局静态数组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,
		35
#endif
#ifdef HAVE_DEVPOLL
		&devpollops,
#endif
#ifdef HAVE_POLL
		&pollops,
#endif
#ifdef HAVE_SELECT
		&selectops,
#endif
#ifdef WIN32
		&win32ops,
#endif
		NULL
};

然后libevent根据系统配置和编译选项决定使用哪一种I/O demultiplex机制,这段代码在函数event_base_new()中:

	base->evbase = NULL;
for (i = 0; eventops[i] && !base->evbase; i++) {
	base->evsel = eventops[i];
	base->evbase = base->evsel->init(base);
}

可以看出,libevent在编译阶段选择系统的I/O demultiplex机制,而不支持在运行阶段根据配置再次选择

以Linux下面的epoll为例,实现在源文件epoll.c中,eventops对象epollops定义如下:

	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 *);

那么如果选择的是epoll,那么调用结构体eventop的init和dispatch函数指针时,实际调用的函数就是epoll的初始化函数epoll_init()和事件分发函数epoll_dispatch()了;

关于epoll的具体用法这里就不多说了,可以参见介绍epoll的文章

C++语言提供了虚函数来实现多态,在C语言中,这是通过函数指针实现的。对于各类函数指针的详细说明可以参见文章

同样的,上面epollops以及epoll的各种函数都直接定义在了epoll.c源文件中,对外都是不可见的。对于libevent的使用者而言,完全不会知道它们的存在,对epoll的使用也是通过eventop来完成的,达到了信息隐藏的目的。

小节

支持多种I/O demultiplex机制的方法其实挺简单的,借助于函数指针就OK了。通过对源代码的分析也可以看出,Libevent是在编译阶段选择系统的I/O demultiplex机制的,而不支持在运行阶段根据配置再次选择。

时间: 2024-08-25 11:41:06

[libevent]支持I/O多路复用技术的相关文章

【Flume】flume的多路复用技术multiplexing

多路复用技术意在可以将一个event根据配置信息发送特定的channel上. A source instance can specify multiple channels, but a sink instance can only specify one channel. Flume supports fanning out the flow from one source to multiple channels. There are two modes of fan out, replic

控制文件的多路复用技术

在Windows操作系统中,如果注册表文件被损坏了,就会影响操作系统的稳定性.严重的话,会导致操作系统无法正常启动.而控制文件对于Oracle数据库来说,其作用就好象是注册表一样的重要.如果控制文件出现了意外的损坏,那么此时Oracle数据库系统很可能无法正常启动.为此作为Oracle数据库管理员,务必要保证控制文件的安全. 在实际工作中,数据库管理员可以通过备份控制文件来提高控制文件的安全性.但是笔者认为这是下下之策.因为当控制文件出现损坏时,通过备份文件来恢复的话,会出现数据库在一段时间内的

Lind.DDD.RedisClient~对StackExchange.Redis调用者的封装及多路复用技术

回到目录 两雄争霸 使用StackExchange.Redis的原因是因为它开源,免费,而对于商业化的ServiceStack.Redis,它将一步步被前者取代,开源将是一种趋势,商业化也值得被我们尊重,毕竟人家研究代码也不容易,做商品也很正常,当然这不是我们今天的重要,今天主要说一下对StackExchange.Redis的封装,它与ServicesStack.redis最大的不同就是,它没有线程池的概念,这对于初学者绝对是个坑,大家使用时一定要注册,StackExchange.redis的对

Tornado从入门到进阶 打造支持高并发的技术论坛

第1章 Tornado从入门到进阶 打造支持高并发的技术论坛-课程导学Tornado从入门到进阶 打造支持高并发的技术论坛-课程导学 第2章 开发环境搭建(会的可以略过本章,2-4要看下哦)本章节主要讲解搭建开发环境,包括navicat.pycharm.virtualenvwrapper的使用,在本章节也会重点介绍课程资源的下载和配置使用. 第3章 为什么要学习tornado很多人会把tornado和flask以及django相提并论,只是知道tornado是高并发的,但是因为对tornado的

多路复用技术

复用的概念是从提高通信的有效性角度提出来的,其主要目的是为了有效地利用带宽.多路复用通常分为频分多路复用.时分多路复用.波分多路复用.码分多址和空分多址. 1. 频分多路复用(FDM,Frequency Division Multiplexing) 频分多路复用的基本原理是:如果每路信号以不同的载波频率进行调制,而且各个载波频率是完全独立的,即各个信道所占用的频带不相互重叠.相邻信道之间用“警戒频带”隔离,那么每个信道就能独立地传输一路信号. 频分多路复用的主要特点是,信号被划分成若干通道(频道

微软宣布在Azure上支持更多的开放技术和选择

微软和我都热爱Linux,并且就在情人节过去几天之后,我非常高兴能用几个激动人心的消息来表达这种对Linux的热爱,您将会看到在Azure上的云部署将具有更加开放的选择性和灵活性. 这些激动人心的消息包含: 红帽企业版(Red Hat Enterprise)Linux镜像操作系统现已在Azure Marketplace市场上线: 正式开始了Azure Container Service容器服务的公开预览: Bitnami镜像授权给微软Azure Marketplace市场:以及 Azure开始支

I/O多路复用技术

典型应用于以下场合 1.处理多个描述字时,比如同时处理套接字和磁盘IO.终端IO 2.一个客户同时处理多个套接字 3.服务器既要处理监听套接字,又要处理已连接套接字 4.既要处理TCP.也要处理UDP 5.一个服务器要处理多个服务和协议 I/O多路复用不局限于网络编程,也可以用于其他程序. UNIX中五种I/O模型 1.阻塞I/O 2.非阻塞I/O 3.I/O多路复用 4.异步I/O 5.信号驱动I/O 信号驱动模型 5种I/O模型的比较 select函数有三种使用方式 1.函数阻塞直至有起码一

Java IO多路复用技术简介

<span style="font-size:18px;">package com.winwill.nio; /** * @author qifuguang * @date 15-2-4 下午2:07 */ public class TimeServerMain { public static void main(String[] args) throws Exception { // 启动时间服务器 new Thread(new SelectorTimeServer())

libevent源码深度剖析十

libevent源码深度剖析十 --支持I/O多路复用技术张亮 Libevent的核心是事件驱动.同步非阻塞,为了达到这一目标,必须采用系统提供的I/O多路复用技术,而这些在Windows.Linux. Unix等不同平台上却各有不同,如何能提供优雅而统一的支持方式,是首要关键的问题,这其实不难,本节就来分析一下. 1 统一的关键 Libevent支持多种I/O多路复用技术的关键就在于结构体eventop,这个结构体前面也曾提到过,它的成员是一系列的函数指针, 定义在event-internal