Libevent之事件循环篇

创建了event_base对象,并且注册了一些事件之后,我们就希望Libevent可以在某个或某些事件被激活的时候能够及时的通知我们。

1.运行事件循环

(1)event_base_loop()

一旦创建了event_base对象并注册了事件之后,就可以通过event_base_loop()开启事件循环:

其中,参数base是一个event_base对象;参数flag,可以用来改变event_base_loop()的行为,其可选值如上所示。

并且,默认情况下,在结束了事件注册之后,才会开启事件循环,该循环会反复的检查已注册事件是否被激活,一旦发现某个事件被激活,就会运行相应的回调函数。

然而,通过flag参数设置一个或多个标志,可以改变event_base_loop()函数的行为:

EVLOOP_ONCE:设置该标志,循环将一直等待直到某些事件被激活,然后运行所有的被激活事件,最后返回;
EVLOOP_NONBLOCK:设置该标志,循环将不再等待某些事件被激活,而是检查是否有事件将要触发,若有,则运行相应的回调函数后返回;
EVLOOP_NO_EXIT_ON_EMPTY:默认情况下,在没有等待事件或没有激活事件之后,循环会退出。设置该标志位,可以改变这一行为。

event_base_loop()函数的一般处理流程如下(伪代码):

(2)event_base_dispatch()

相比于event_base_loop(),使用event_base_dispatch()函数更加容易使用,该函数不需要指定flag标志位。因此,该函数会一直运行,直到没有更多的注册事件或者直到遇到event_base_loopbreak()或event_base_loopexit()函数退出为止。

2.停止事件循环

通过下面的两个函数,可以让一个循环在所有注册事件被删除之前停止:

(1)event_base_loopexit()

需要注意的是:如果tv为NULL,则立刻终止循环。但是,如果此时正在处理某个事件的回调函数,则会等到其执行完之后再终止循环。

(2)event_base_loopbreak()

需要注意的是:该函数不同于调用event_base_loop(base, NULL);,因为后者会等待正在运行的回调函数结束才终止,而前者不然。

3.再次检查事件

通常,Libevent的循环机制是:循环检查事件==》运行所有激活的事件==》接着再检查事件……但是,有时我们会在某个事件回调函数执行之后停止Libevent循环(如前所述)。若想让Libevent再次扫描检查事件,则需要调用下面这个函数:

4.其他

其他可能会用到的函数还有:

(1)获取时间
int event_base_gettimeofday_cached(struct event_base *base, struct timeval *tv_out);

获取当前时间,而不是使用系统调用gettimeofday()。

(2)更新时间
int event_base_update_cache_time(struct event_base *base);

参考:
http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注