[libevent]事件主循环

libevent的事件主循环通过event_base_loop函数实现,统一处理I/O、Timer和Signal事件。利用堆数据结构管理Timer事件,通过调整I/O机制的timeout时间来处理Timer。Signal事件通过通知I/O机制在合适时机处理。event_base_loop可按不同标志运行,如EVLOOP_ONCE、EVLOOP_NONBLOCK。event_base_loopexit和event_base_loopbreak用于控制循环的退出方式。
摘要由CSDN通过智能技术生成

libevent事件处理的中心部分——事件主循环,根据系统提供的事件多路分发机制执行事件循环,对已注册的就绪事件,调用注册事件的回调函数来处理事件。

事件处理主循环

libevent的事件主循环主要是通过event_base_loop ()函数完成的,其主要操作如下面的流程图所示,event_base_loop所作的就是持续执行下面的循环。

 

 上图的简单描述就是:

  1. 校正系统当前时间。
  2. 将当前时间与存放时间的最小堆中的时间依次进行比较,将所有时间小于当前时间的定时器事件从堆中取出来加入到活动事件队列中。
  3. 调用I/O封装(比如:Epoll)的事件分发函数dispatch函数,以当前时间与时间堆中的最小值之间的差值(最小堆取最小值复杂度为O(1))作为Epoll/epoll_wait(Epoll.c/dispatch/407)timeout值,在其中将触发的I/O和信号事件加入到活动事件队列中。
  4. 调用函数event_process_active(Event.c/1406)遍历活动事件队列,依次调用注册的回调函数处理相应事件。

int event_base_loop(struct event_base *base, int flags)
{
	const struct eventop *evsel = base->evsel;
	void *evbase = base->evbase;
	struct timeval tv;
	struct timeval *tv_p;
	int res, done;
	// 清空时间缓存
	base->tv_cache.tv_sec = 0;
	// evsignal_base是全局变量,在处理signal时,用于指名signal所属的event_base实例
	if (base->sig.ev_signal_added)
		evsignal_base = base;
	done = 0;
	while (!done) { // 事件主循环
		// 查看是否需要跳出循环,程序可以调用event_loopexit_cb()设置event_gotterm标记
		// 调用event_base_loopbreak()设置event_break标记
		if (base->event_gotterm) {
			base->event_gotterm = 0;
			break;
		}
		if (base->event_break) {
			base->event_break = 0;
			break;
		}
		// 校正系统时间,如果系统使用的是非MONOTONIC时间,用户可能会向后调整了系统时间
		// 在timeout_correct函数里,比较last wait time和当前时间,如果当前时间< last wait time
		// 表明时间有问题,这是需要更新timer_heap中所有定时事件的超时时间。
		timeout_correct(base, &tv);
		// 根据timer heap中事件的最小超时时间,计算系统I/O demultiplexer的最大等待时间
		tv_p = &tv;
		if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
			timeout_next(base, &tv_p);
		} else {
			// 依然有未处理的就绪时间,就让I/O demultiplexer立即返回,不必等待
				// 下面会提到,在libevent中,低优先级的就绪事件可能不能立即被处理
				evutil_timerclear(&tv);
		}
		//
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值