[libevent]event/event_base/epollop/evsignal_info分析

经过了一个月对libevent1.4.13源码的学习,并且自己仿照了,码了一个c++版的,现在分享一下自己对源码关于epoll的一些分析。

 

学习源码的过程并挺好玩的,给想学习的同学以下建议:

1.source insight来看代码,非常方便,各种跳转功能和高亮,多窗口。

2.可以看看张亮的分析,没有说对源码全部一句一句分析,其实也没必要,他讲得比较全面,剩下的代码自己完全可以看懂,我就是看他的学习的~


不过在那之前我们先解释下event/event_base/epollop/evsignal_info的分析:

struct event {
	TAILQ_ENTRY (event) ev_next;                   //读写和信号事件在事件链表的位置
	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;					//每个事件关联的事件框架

	int ev_fd;		//读写事件为文件描述符,信号事件为信号值,定时事件设置为-1
	short ev_events;							//事件的类型
	short ev_ncalls;							//回调函数要执行的次数
	short *ev_pncalls;	/* Allows deletes in callback *///一般指向上面那个变量,用来中断回调函数的执行用

	struct timeval ev_timeout; 					 //定时事件的定时结束时间

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

	void (*ev_callback)(int, short, void *arg);   		//回调函数
	void *ev_arg;								//用作回调函数的第三个参数

	int ev_res;		/* result passed to event callback *///当前激发(就绪)的事件
	int ev_flags;								//当前所在的链表类型
};

struct event_base {
	const struct eventop *evsel;   //统一事件的机制,比如在linux下它就会选择epoll机制
	void *evbase;				//如果上面选择了epoll机制,那么这个其实就是epoll.c里面的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;   //具有优先级(因为双指针)的就绪事件链表
	int nactivequeues;				//最大优先级,其实就是优先级的等级范围

	/* signal handling info */
	struct evsignal_info sig;			//用来管理信号事件用的,有一系列操作在signal.c

	struct event_list eventqueue;		//注册后信号事件或者读写事件所在的事件链表
	struct timeval event_tv;			//用作时间修正

	struct min_heap timeheap;		//存定时事件的小根堆

	struct timeval tv_cache;			//保存现在的时间,其实直接用系统函数就可以得到当前时间,但是费时,所以就用这个来缓存下当前时间,就不用一直用系统调用了。
};
struct evepoll {
	struct event *evread;
	struct event *evwrite;
};

struct epollop {
	struct evepoll *fds;    		//因为我们用的是epoll_wait来统一事件,所以需要一个文件描述符对应一个epoll_event和event,这个链表作用是用来关联epoll_event结构的,关联后用epoll_wait后可得到第二个参数,即epoll_event*链表,后面可以对对应的event做处理,比如插入就绪链表等动作。
	int nfds;					//最大文件描述符值
	struct epoll_event *events;	//跟evepoll 关联的事件链表
	int nevents;				//用epoll_wait得到的第三个参数,即events的大小
	int epfd;					//epoll_create得到的管理文件描述符
};

struct evsignal_info {
	struct event ev_signal;     //用一对socket来统一所有的信号的事件,大概是信号来就调用一个函数(evsignal_handler(写)),然后因为注册了一个event读事件(ev_signal),由epoll_wait得到这个事件后,调用回调函数(evsignal_cb),在(evsignal_handler)的过程已经记录了哪个信号触发了,即以下结构记录的
//struct evsignal_info sig;			//用来管理信号事件用的,有一系列操作在signal.c
//这个类记录了之后后面的循环会把对应触发的信号的回调函数执行。

	int ev_signal_pair[2];    //注册的一对socket
	int ev_signal_added;	//是否已注册信号
	volatile sig_atomic_t evsignal_caught;		//是否有信号触发
	struct event_list evsigevents[NSIG];		//信号链表,所有注册的信号都在此链表
	sig_atomic_t evsigcaught[NSIG];			//对应信号的触发次数
#ifdef HAVE_SIGACTION
	struct sigaction **sh_old;				//这个其实是用来恢复注册信号的回调函数的,比如你在程序另一边也注册了这个信号的回调函数,但是这边又用libevent注册了,那么在这个框架结束后它会帮你恢复之前的回调函数。
#else
	ev_sighandler_t **sh_old;
#endif
	int sh_old_max;                      //能恢复信号的回调函数的最大数量
}


弄清楚各个成员的含义对后面看代码特别重要~下一篇我们讲函数的分析~



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值