libevent的event处理框架剖析

前几次剖析了libevent的tail queue和evbuffer,今天来剖析一下它的事件处理框架。这个在剖析evbuffer之前已经大致走过几遍,但思路不是很清晰,是因为我没有用实例去测试event流程。通过这次我学习到了剖析源码不仅要去看源码,而且你要测试它这项接口是怎么用的,不然只会似懂非懂。

首先来看一下event结构体:

struct event {
	TAILQ_ENTRY (event) ev_next;  //已注册事件链表,名字叫ev_next,event是类型,非活跃, TAILQ_ENTRY在我之前的博客已经剖析过了,不再赘述
	TAILQ_ENTRY (event) ev_active_next;   //活跃事件链表,叫链表或者队列都行,下文碰见队列也是说这几个
	TAILQ_ENTRY (event) ev_signal_next;   //信号事件链表
	unsigned int min_heap_idx;	/* for managing timeouts */ //超时事件在小根堆中的索引
										
	struct event_base *ev_base;  //该事件所属的反应堆实例,它指向一个event_base反应堆

	int ev_fd;                //对于IO事件是文件描述符,对于信号事件,是绑定的信号
	short ev_events;   //关注的事件类型,如EV_WRITE,EV_READ,EV_TIMEOUT,EV_SIGNAL,EV_PRESIST,可以使用|组合
	short ev_ncalls;      //事件就绪时,调用ev_callback执行的次数,通常为1
	short *ev_pncalls;	/* Allows deletes in callback */    //通常指向event_ncalls,或者为NULL

	struct timeval ev_timeout;    //超时事件的超时值

	int ev_pri;		/* smaller numbers are higher priority */   //优先级

	void (*ev_callback)(int, short, void *arg);   //event回调函数,执行事件处理程序,fd对应ev_fd,events对应
									        //ev_events, arg对应ev_arg
	void *ev_arg;         //设置event时指定                         

	int ev_res;		/* result passed to event callback */  //记录了当前激活事件的类型
	int ev_flags;     //标记event信息的字段,表明当前状态,如EVLIST_TIMEOUT, EVLIST_INSERTED, EVLIST_ACTIVE等。
};
下面是event_base结构体:

struct event_base {
	const struct eventop *evsel;  //用来接收系统编译前设置I/O机制的名字,来自eventops
	void *evbase;     //接收init返回的I/O多路复用的op,如epollop
	int event_count;		/* counts number of total events */  //事件总数
	int event_count_active;	/* counts number of active events */   //活跃事件数目

	int event_gotterm;		/* Set to terminate loop */  
	int event_break;		/* Set to terminate loop immediately */

	/* active event management */
	struct event_list **activequeues; //activequeues[priority]是一个链表,链表中的每个结点都是优先级为
	 							  //priority的就绪事件event
	int nactivequeues;          //活跃链表的数目

	/* signal handling info */
	struct evsignal_info sig;      //专门管理信号的结构体

	struct event_list eventqueue;   //链表,保存了所有注册事件event的指针
	struct timeval event_tv;       //管理时间变量

	struct min_heap timeheap;   //用来管理定时时间的小根堆

	struct timeval tv_cache;   //管理时间变量
};
event_base中的evsel的类型是eventop类型,它的结构体是这样的:

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;    //设置是否重新初始化
};

eventop即event operator,我们可以看到它的内部封装了事件操作的名字,以及各种方法,可以用来配合实现C语言的多态。这里实际上将会封装I/O多路复用选项,比如:name=epoll,然后init,add等方法就用epoll的方法,或者name=select,用select的方法。至于怎么选,看下面。

evsel实际上会在event_base_new函数里面初始化,会根据你在编译前的选项来选择I/O multiplexer,我把ecent_base_new函数中选择部分截取出来如下,以及eventops选项数组。

        //根据系统配置和编译选项决定使用哪一种I/O demultiplex机制
	//可以看出,libevent在编译阶段选择系统的I/O demultiplex机制,而不支持在运行阶段根据配置再次选择
	base->evbase = NULL;
	fo
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值