Libevent源码分析(三)——源代码结构及事件event

前言

有了前面两节的铺垫,应该对Reactor模式和libevent中的基本流程有了一个基本的认识,接下来我们就可以分析源代码啦,不过在分析源代码之前,我们先来看一下源码结构。

絮叨

我在第一次把源代码下载下来的时候,一看代码,我有点懵,心想,libevent怎么这么随意,把代码文件都放在了一个文件下,也太乱了,然而并不是这样,仔细一研究,就发现,其实代码结构是非常清晰的。一起来看看吧:

代码结构
  1. 头文件:event.h:负则事件宏定义、声明接口函数、声明事件结构体event;
  2. 内部头文件:***-internal.h:内部的数据结构和函数,封装了供内部使用;
  3. event.c:event整体实现;
  4. 对I/O多路转接的封装 :epoll.c、select.c、devpoll.c、kqueue.c
  5. 定时器事件管理:min-heap.h:维护了一个小根堆管理时间
  6. 信号管理:signal.c:负则信号事件
  7. 辅助功能函数/工具函数:evuti.h evutil.c一些工具函数
  8. 日志:log.h log.c:负责打印日志信息
  9. 缓冲区:evbuffer.c buffer.c:负责管理缓冲区
  10. 数据结构:compat/sys下面的两个文件,封装了基本的数据结构链表队列等。
  11. 网络库:libevent实现了一个http服务器还有一个异步的dns查询库
小结:

这就是整个结构,其实是很清晰明了的

事件

事件是libevent的一个核心,看名字就知道了,的确libevent是由事件驱动的,整个工作都围绕着事件展开

struct event {
	//事件对应的回调函数
	struct event_callback ev_evcallback;

	/* for managing timeouts */
	//管理超时事件的,维护了一个小根堆,min_heap_idx小根堆中的索引,ev_next_with_common_timeout超时的指针
	union {
		TAILQ_ENTRY(event) ev_next_with_common_timeout;
		int min_heap_idx;
	} ev_timeout_pos;
	//句柄,之前是int ev_fd;
	evutil_socket_t ev_fd;

	//这个就是事件关联的Reactor,后续会说的
	struct event_base *ev_base;

	union {
		/* used for io events */
		//对于I/O事件的指针和时间
		struct {
			LIST_ENTRY (event) ev_io_next;
			struct timeval ev_timeout;
		} ev_io;

		/* used by signal events */
		struct {
		//维护信号事件的指针
			LIST_ENTRY (event) ev_signal_next;
			//回调函数的执行次数
			short ev_ncalls;
			/* Allows deletes in callback */
			//指向上面变量的指针
			short *ev_pncalls;
		} ev_signal;
	} ev_;
	//事件类型有几种宏,后面再说
	short ev_events;
	//记录事件的激活类型
	short ev_res;		/* result passed to event callback */
	//超时时间
	struct timeval ev_timeout;
};

在c语言中,封装一些东西就是使用结构体,一层又一层,看起来十分复杂,好的封装,看起来又是井井有条,体现了设计者的智慧。
这一个版本比之前的封装了更多东西,大体还是没变的。

重点,libevent的事件管理:

从event结构体中,我们大致可以看出,其中有一个小根堆,一个激活事件的链表,一个注册I/O事件链表和一个信号事件链表。libevent的管理,其实就是不断地更新这些链表的状态,大体结构是这样,它的设计还有很多巧妙之处,我们后续再看。贴张图吧:

事件的接口函数

创建事件函数的原型:

struct event *event_new(struct event_base *base, evutil_socket_t fd,short what, event_callback_fn cb, void *arg);

使用这个函数可以获得一个事件对象:
base:就是Reactor,fd可以是文件描述符,或者socket等,也就是句柄,

what:是下面的集合,表示事件的类型
在这里插入图片描述
cb是回调函数,arg是参数
设置事件的优先级:当ev处于激活状态时不能设置,会返回-1

int event_priority_set(struct event *event, int priority);

注册事件:就是让事件被检测,后面会再说

int event_add(struct event *ev, const struct timeval *tv);

还有一些接口,后面会再继续说的。

总结

event是libevent的核心结构,整个libevent就是对各种事件的处理,切换事件的状态,然后去调用事件的回调函数,这就是libevent最核心的东西。

愿每一个程序员都能被温柔相待

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。 编辑本段 详细   编译库代码,编译脚本会判断OS支持哪种类型的事件机制(select、epoll或kqueue),然后条件编译相应代码,供上层使用的接口仍然是保持统一的(否则也不能所谓的跨平台了)。在linux redhat as 4 u 2 上编译相当容易,configure以后make,make install就可以了,windows上编译似乎有点小麻烦,不过稍微改点东西也就通过了。   从代码中看,libevent支持用户使用种类型的事件,分别是网络IO、定时器、信号种,在定时器的实现上使用了RB tree的数据结构,以达到高效查找、排序、删除定时器的目的,网络IO上,主要关注了一下linux上的epoll(因为目前的开发主要在linux平台),结果发现libevent的epoll居然用的EPOLLLT,水平触发的方式用起来比较方便,不容易出错,但是在效率上可能比EPOLLET要低一些。   跟网络无关的,libevent也有一些缓冲区管理的函数,而且是c风格的函数,实用性不是太大。libevent没有提供缓存的函数。   虽然libevent实用上的价值不大,但它提供的接口形式还是不错的,实现类似的lib的时候仍然是可以参考的。   Libevent定时器的数据结构自version 1.4起已由红黑树改为最小堆(Min Heap),以提高效率;网络IO和信号的数据结构采用了双向链表(TAILQ)。在实现上主要有3种链表: EVLIST_INSERTED, EVLIST_ACTIVE, EVLIST_TIMEOUT,一个ev在这3种链表之间被插入或删除,处于EVLIST_ACTIVE链表中的ev最后将会被调度执行。   Libevent提供了DNS,HTTP Server,RPC等组件,HTTP Server可以说是Libevent的经典应用。从http.c可看到Libevent的很多标准写法。写非阻塞式的HTTP Server很容易将socket处理与HTTP协议处理纠缠在一起,Libevent在这点上似乎也有值得推敲的地方。
luotuo44是一个GitHub上的开源项目,其主要目的是分析libevent源码libevent是一个使用C语言编写的事件驱动库,可以用于开发高性能的网络服务器和客户端应用程序。 在分析libevent源码时,luotuo44首先研究了libevent的基本结构和使用方法。他深入研究了libevent事件循环机制、事件触发方式以及事件回调函数的实现原理。通过仔细阅读源代码,他详细解释了libevent是如何利用系统底层的IO多路复用技术(如select、epoll等)来实现高效的事件处理。 此外,luotuo44还分析libevent的缓冲区管理和事件优先级处理机制。他对libevent的缓冲区数据结构和操作进行了详细解读,包括如何实现缓冲区的读写以及缓冲区事件的触发和处理。他还深入探讨了libevent事件优先级机制,介绍了如何设置和管理不同优先级的事件,并解释了事件优先级对事件处理效率的影响。 除了基本功能外,luotuo44还分析libevent的线程安全性和性能优化策略。他详细讲解了libevent的线程安全机制,包括互斥锁、条件变量等,并提供了一些最佳实践指南,以确保多线程环境下的稳定性和性能。此外,他还分享了一些他自己的性能优化经验,包括使用合适的数据结构、避免频繁内存分配与释放等。 总的来说,luotuo44的libevent源码分析为那些想深入了解libevent内部原理和如何正确使用libevent的开发者提供了很大的帮助。通过他的分析,读者可以更好地理解libevent的工作原理,并从中学习到一些编程技巧和优化策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值