【传智播客】Libevent学习笔记(三):事件循环
目录
- 00. 目录
- 01. event_base_loop函数
- 02. event_base_dispatch函数
- 03. event_base_loopexit函数
- 04. event_base_loopbreak函数
- 05. event_base_got_exit函数
- 06. event_base_got_break函数
- 07. event_base_dump_events函数
- 08. event_base_dump_events函数
- 09. 废弃的事件循环函数
- 10.参考
00. 目录
声明: 该博客来源于传智播客C++学院相关培训参考手册
01. event_base_loop函数
一旦有了一个已经注册了某些事件的event_base(关于如何创建和注册事件请看笔记四),就需要让libevent等待事件并且通知事件的发生。
event_base_loop函数
/**Wait for events to become active, and run their callbacks.This is a more flexible version of event_base_dispatch().By default, this loop will run the event base until either there are no morepending or active events, or until something calls event_base_loopbreak() orevent_base_loopexit(). You can override this behavior with the 'flags'argument.@param eb the event_base structure returned by event_base_new() orevent_base_new_with_config()@param flags any combination of EVLOOP_ONCE | EVLOOP_NONBLOCK@return 0 if successful, -1 if an error occurred, or 1 if we exited becauseno events were pending or active.@see event_base_loopexit(), event_base_dispatch(), EVLOOP_ONCE,EVLOOP_NONBLOCK*/
int event_base_loop(struct event_base *base, int flag); //while(1) { .... }
功能:等待事件被触发, 然后执行对应的回调函数
参数:base: event_base_new的返回值flag: 标志
返回值:成功: 0成功 1表示没有事件触发失败: -1
循环相关标志:
/** @name Loop flagsThese flags control the behavior of event_base_loop().*/
/**@{*/
/** Block until we have an active event, then exit once all active events* have had their callbacks run. */
#define EVLOOP_ONCE 0x01
/** Do not block: see which events are ready now, run the callbacks* of the highest-priority ones, then exit. */
#define EVLOOP_NONBLOCK 0x02
/**@}*/
默认情况下,event_base_loop()函数运行event_base直到其中没有已经注册的事件为止。执行循环的时候,函数重复地检查是否有任何已经注册的事件被触发(比如说,读事件的文件描述符已经就绪,可以读取了;或者超时事件的超时时间即将到达)。如果有事件被触发,函数标记被触发的事件为“激活的”,并且执行这些事件。
在flags参数中设置一个或者多个标志就可以改变event_base_loop()的行为。如果设置了EVLOOP_ONCE,循环将等待某些事件成为激活的,执行激活的事件直到没有更多的事件可以执行,然会返回。如果设置了EVLOOP_NONBLOCK,循环不会等待事件被触发:循环将仅仅检测是否有事件已经就绪,可以立即触发,如果有,则执行事件的回调。
完成工作后,如果正常退出,event_base_loop()返回0;如果因为后端中的某些未处理错误而退出,则返回-1。
为帮助大家理解,这里给出event_base_loop()的算法概要:
while (any events are registered with the loop) {if (EVLOOP_NONBLOCK was set, or any events are already active)If any registered events have triggered, mark them active.elseWait until at least one event has triggered, and mark it active.for (p = 0; p < n_priorities; ++p {if (any event with priority of p is active) {Run all active events with priority of p.break; /* Do not run any events of a less important priority */}}if (EVLOOP_ONCE was set or EVLOOP_NONBLOCK was set)break;
}
02. event_base_dispatch函数
event_base_dispatch()等同于没有设置标志的event_base_loop()。所以,event_base_dispatch()将一直运行,直到没有已经注册的事件了,或者调用了event_base_loopbreak()或者event_base_loopexit()为止。
/**Event dispatching loopThis loop will run the event base until either there are no more pending oractive, or until something calls event_base_loopbreak() orevent_base_loopexit().@param base the event_base structure returned by event_base_new() orevent_base_new_with_config()@return 0 if successful, -1 if an error occurred, or 1 if we exited becauseno events were pending or active.@see event_base_loop()*/
int event_base_dispatch(struct event_base *base);
等价于没有设置标志的 event_base_loop函数
event_base_dispatch()将一直运行,直到没有已经注册的事件了,或者调用了event_base_loopbreak()或者event_base_loopexit()为止。
这些函数定义在<event2/event.h>中,从libevent 1.0版就存在了。
03. event_base_loopexit函数
/**Exit the event loop after the specified timeThe next event_base_loop() iteration after the given timer expires willcomplete normally (handling all queued events) then exit withoutblocking for events again.Subsequent invocations of event_base_loop() will proceed normally.@param eb the event_base structure returned by event_init()@param tv the amount of time after which the loop should terminate,or NULL to exit after running all currently active events.@return 0 if successful, or -1 if an error occurred@see event_base_loopbreak()*/
int event_base_loopexit(struct event_base *base, const struct timeval *tv);
功能:让event_base在给定时间之后停止循环。
参数:base event_base_new的返回值tv 表示延时的时间,如果为NULL 立即停止循环,没有延时返回值:成功: 0成功 失败: -1
注意:
如果event_base当前正在执行任何激活事件的回调,则回调会继续运行,直到运行完所有激活事件的回调之才退出。
04. event_base_loopbreak函数
/**Abort the active event_base_loop() immediately.event_base_loop() will abort the loop after the next event is completed;event_base_loopbreak() is typically invoked from this event's callback.This behavior is analogous to the "break;" statement.Subsequent invocations of event_loop() will proceed normally.@param eb the event_base structure returned by event_init()@return 0 if successful, or -1 if an error occurred@see event_base_loopexit()*/
int event_base_loopbreak(struct event_base *base);
功能:让event_base立即停止循环。
参数:base event_base_new的返回值
返回值:成功: 0成功 失败: -1
这些函数声明在<event2/event.h>中。event_break_loopexit()函数首次在libevent 1.0c版本中实现;event_break_loopbreak()首次在libevent 1.4.3版本中实现。
注意:
event_base_loopbreak()让event_base立即退出循环。它与event_base_loopexit(base,NULL)的不同在于,如果event_base当前正在执行激活事件的回调,它将在执行完当前正在处理的事件后立即退出。
event_base_loopexit(base,NULL)和event_base_loopbreak(base)在事件循环没有运行时的行为不同:前者安排下一次事件循环在下一轮回调完成后立即停止(就好像带EVLOOP_ONCE标志调用一样);后者却仅仅停止当前正在运行的循环,如果事件循环没有运行,则没有任何效果。
官方参考示例一: 立即退出循环
#include <event2/event.h>/* Here's a callback function that calls loopbreak */
void cb(int sock, short what, void *arg)
{struct event_base *base = arg;event_base_loopbreak(base);
}void main_loop(struct event_base *base, evutil_socket_t watchdog_fd)
{struct event *watchdog_event;/* Construct a new event to trigger whenever there are any bytes toread from a watchdog socket. When that happens, we'll call thecb function, which will make the loop exit immediately withoutrunning any other active events at all.*/watchdog_event = event_new(base, watchdog_fd, EV_READ, cb, base);event_add(watchdog_event, NULL);event_base_dispatch(base);
}
官方参考示例二: 执行事件循环10秒,然后退出
#include <event2/event.h>void run_base_with_ticks(struct event_base *base)
{struct timeval ten_sec;ten_sec.tv_sec = 10;ten_sec.tv_usec = 0;/* Now we run the event_base for a series of 10-second intervals, printing"Tick" after each. For a much better way to implement a 10-secondtimer, see the section below about persistent timer events. */while (1) {/* This schedules an exit ten seconds from now. */event_base_loopexit(base, &ten_sec);event_base_dispatch(base);puts("Tick");}
}
测试代码: 每隔3秒钟输出一个字符串
#include <stdio.h>
#include <event.h>int main(void)
{struct event_base *base = NULL;struct timeval tmo = {3, 0}; base = event_base_new();if (NULL == base){ printf("event_base_new failded...\n");return 1;}while(1){ //设置三秒钟退出事件循环event_base_loopexit(base, &tmo); //进入事件循环event_base_dispatch(base);printf("hello itcast\n");}event_base_free(base);return 0;
}
05. event_base_got_exit函数
有时候需要知道对event_base_dispatch()或者event_base_loop()的调用是正常退出的,还是因为调用event_base_loopexit()或者event_base_break()而退出的。可以调用下述函数来确定是否调用了loopexit或者break函数。
/**Checks if the event loop was told to exit by event_loopexit().This function will return true for an event_base at every point afterevent_loopexit() is called, until the event loop is next entered.@param eb the event_base structure returned by event_init()@return true if event_base_loopexit() was called on this event base,or 0 otherwise@see event_base_loopexit()@see event_base_got_break()*/
int event_base_got_exit(struct event_base *base);
功能:判断循环是否因为调用event_base_loopexit()或者event_base_break()而退出的时候返回true,否则返回false。下次启动事件循环的时候,这些值会被重设。
参数:base event_base_new的返回值
返回值:true 循环是因为调用对应的函数而退出0 其它情况
参考示例:
#include <stdio.h>
#include <event.h>int main(void)
{struct event_base *base = NULL;struct timeval tmo = {3, 0}; base = event_base_new();if (NULL == base){ printf("event_base_new failded...\n");return 1;} while(1){ event_base_loopexit(base, &tmo);event_base_dispatch(base);printf("hello itcast\n");//如果事件循环因为event_base_loopexit而退出 返回trueif (event_base_got_exit(base)){printf("event_base_got_exit return true\n");}} event_base_free(base);return 0;
}
06. event_base_got_break函数
有时候需要知道对event_base_dispatch()或者event_base_loop()的调用是正常退出的,还是因为调用event_base_loopexit()或者event_base_break()而退出的。可以调用下述函数来确定是否调用了loopexit或者break函数。
/**Checks if the event loop was told to abort immediately by event_loopbreak().This function will return true for an event_base at every point afterevent_loopbreak() is called, until the event loop is next entered.@param eb the event_base structure returned by event_init()@return true if event_base_loopbreak() was called on this event base,or 0 otherwise@see event_base_loopbreak()@see event_base_got_exit()*/
int event_base_got_break(struct event_base *base);
功能:判断循环是否因为调用event_base_loopexit()或者event_base_break()而退出的时候返回true,否则返回false。下次启动事件循环的时候,这些值会被重设。
参数:base event_base_new的返回值
返回值:true 循环是因为调用对应的函数而退出0 其它情况
07. event_base_dump_events函数
有时候需要在事件回调中获取当前时间的近似视图,但不想调用gettimeofday()(可能是因为OS将gettimeofday()作为系统调用实现,而你试图避免系统调用的开销)。
在回调中,可以请求libevent开始本轮回调时的当前时间视图。
void event_base_dump_events(struct event_base *, FILE *);/** Sets 'tv' to the current time (as returned by gettimeofday()),looking at the cached value in 'base' if possible, and callinggettimeofday() or clock_gettime() as appropriate if there is nocached time.Generally, this value will only be cached while actuallyprocessing event callbacks, and may be very inaccuate if yourcallbacks take a long time to execute.Returns 0 on success, negative on failure.*/
int event_base_gettimeofday_cached(struct event_base *base,struct timeval *tv);
如果event_base当前正在执行回调,event_base_gettimeofday_cached()函数设置tv_out参数的值为缓存的时间。否则,函数调用evutil_gettimeofday()获取真正的当前时间。成功时函数返回0,失败时返回负数。返回值:成功 0失败 负数
注意:
注意,因为libevent在开始执行回调的时候时间值会被缓存,所以这个值至少是有一点不精确。如果回调执行很长时间,这个值将非常不精确。
这个函数是libevent 2.0.4-alpha新引入的。
08. event_base_dump_events函数
为帮助调试程序(或者调试libevent),有时候可能需要已经加入到event_base的所有事件及其状态的完整列表。调用event_base_dump_events()可以将这个列表输出到指定的文件中。
这个列表是人可读的,未来版本的libevent将会改变其格式。
void event_base_dump_events(struct event_base *base, FILE *file);
功能:转储event_base的状态到文件中。
参数:base event_base_new的返回值file FILE类型指针返回值:无
这个函数在libevent 2.0.1-alpha版本中引入。
09. 废弃的事件循环函数
前面已经讨论过,老版本的libevent 具有“当前”event_base的概念。
本文讨论的某些事件循环函数具有操作当前event_base的变体。除了没有base参数外,这些函数跟当前新版本函数的行为相同。
2.0版本之前的event_base是不支持锁的,所以这些函数并不是完全线程安全的:不允许在执行事件循环的线程之外的其他线程中调用*_loopbreak()或者_loopexit()*函数。
10.参考
相关书籍: http://www.wangafu.net/~nickm/libevent-book/Ref2_eventbase.html
官方参考网站: https://www.monkey.org/~provos/libevent/doxygen-2.0.1/index.html
转载于:https://www.cnblogs.com/szitcast/p/10975682.html
【传智播客】Libevent学习笔记(三):事件循环相关推荐
- 传智播客c#学习笔记1
1..Net平台 .Net FrameWork框架 .Net FrameWork框架提供了一个稳定的运行环境,来保障我们.Net平台正常的运转. 2.C#语言 c sharp 编程语言:计算机能够听 ...
- 传智播客Android视频教程——第三天
传智播客Android视频教程--第三天 2012-03-29 查看应用输出的错误信息与如何部署应用到真实手机 软件安装或者运行错误,错误信息会打印在LogCat中. 可以筛选信息,pid.tag. ...
- 传智播客html css3笔记,传智播客详解Css3九大常用属性
在Css3的学习和实际操作中,我们经常会接触到一些常用属性,比如字体.文本.列表和背景等.下面,传智播客将对常用的Css3九大属性进行详解. 1.传智播客详解Css3九大常用属性-字体 l Font- ...
- 传智播客软件测试学习视频汇总:
课程名称 分类 URL 提取码 软件测试入门到精通 视频 http://yun.itheima.com/course/490.html?aoe cnj1 资料 https://pan.baidu.co ...
- 快速上手系列:传智播客Java基础笔记
配置环境,把JDK的bin所在路径复制到Path,末尾加; 基本语法 二 标识符 (1)就是给类,接口,方法,变量等起名字的字符序列 (2)组成规则:A:英文大小写字母 B:数字 C:$ ...
- 传智播客开课的第三天
讲师:徐文海 地址:北京信息科技大学图书馆 时间:7.21 首先徐老师小结了下前天的知识,对jdk的安装.环境变量.常量.变量等知识进行了复习. 今天的学习内容开始了,程序流程控制:顺序结 ...
- 传智播客C语言笔记一:C语言课程概述
什么是语言,什么是C语言,有什么区别于联系呢? 一提到语言这个词,人们自然想到的是像英语.汉语等这样的自然语言,因为它是人和人相互交流信息不可缺少的工具.大家听到我们之间交流的就是汉语,英语.比如一些 ...
- 传智播客视频学习 ---- 字符串含义( C 语言中)
C 语言中字符串的含义: C语言的字符串是以 '\0' 结尾的字符串 C语言中没有字符串的类型,是用字符数组来模拟字符串的 字符串的内存分配可以是 堆上 栈上 全局区上 字符串数组 其实就是一个指针, ...
- java从小白到老白⑤——传智播客27版笔记
今天主要说些内部类的相关基础知识,如果能做出下面这个小题目,再下面的内容不看也罢(面试题答案在最后) 内部类面试题:补全下列代码,实现目标输出,其中描述阶段的数字只能调用已有变量,不能用其他方式 pu ...
- 传智播客免费IT学习资源站-视频库隆重上线
为优化学员对传智播客官网"视频下载"频道的使用体验,方便学员更及时.便捷.精准地获取高质量.更前沿的教学视频资源,加强自学效果,巩固课堂知识,传智播客将原"视频下载&qu ...
最新文章
- ROS系统中实现点云聚类(realsense数据源)
- bootstrap的两种在input框后面增加一个图标的方式
- 【原创】多线程应用中pthread库使用问题
- JAVA入门级教学之(IDEA工具的快捷键和简单设置)
- SQL Server 2005 Analysis Services实践(一)
- React17事件委托的变更
- Kubernetes Secret
- visio一分二的箭头_Microsoft Office Visio绘画双箭头直线的具体步骤介绍
- usboot应用两篇:用USBOOT修理移动硬盘等
- 2022-2028年中国抽水蓄能电站设备制造行业市场竞争态势及发展趋向分析报告
- Linux 网卡配置eth1修改为eth0
- js室内地图开发_支付宝小程序室内地图导航开发-支付宝小程序JS加载esmap地图...
- “魅力河南 智慧富民——互联网+旅游扶贫项目”签约仪式在郑州举行
- 母亲大人辛苦了(snowfall.jquery实现爱心掉落)
- 超声影像对2010 ACR/EULAR RA分类标准的影响: 结合两种不同的受累关节灰阶滑膜炎超声定义的分类标准...
- (2021年)IT技术分享社区个人文章汇总(编程技术篇)
- Nvidia AGX Xavier GMSL 自动驾驶控制器设计方案
- 计算机更新并关机能关闭吗,win10关机不想更新并关机而是直接关机步骤设置
- 魔法师鬼剑士地下城java_DNF新职业加入鬼剑士全家桶 魔法师又多一个萌宝
- proc_mkdir与proc_create