libevent与libev简介_libevent libev-程序员宅基地

技术标签: 笔记  

libevent和libev都是c语言实现的异步事件库,主要封装了三个事件,让我们在开发时不需要关注网络IO事件对应的细节,以及定时事件中应使用的数据结构,以及何时调用定时任务,所以只需要关注简单的注册和回调流程。这三个事件是网络io事件,定时事件,信号事件。

libevent和libev区别

libev在libevent基础上做了一些优化。

多线程问题

libevent由于过度依赖全局变量,没有携带上下文信息,对多线程不太友好,需要考虑加锁的问题。libev在注册事件时携带了callback函数,把所需的上下文(具体的事件、事件所依赖的管理器如epoll)给携带过来,方便做多线程。

定时任务

libevent和libev都是使用最小堆来管理定时任务,区别在于libevent使用的是二叉树,而libev使用四叉树。这个区别在定时事件>50000时,libev会有5% 的性能提升。此外,libev定时器支持具体时间的设置。

额外的组件

libevent实现了很多http组件(如dns、openssl等),实现了很多具体的协议,杂糅在具体网络IO的封装中,而libev只关注网络事件的封装,包括bufferevnt和evconnlistener都没有。但是,作为优化,libev还是封装了libevent同样的接口。

对windows支持

libev对于windows的支持不太友好,主要体现在iocp上,因此有了libuv,在libev上封装了一层iocp。

libevent特点

bufferevent

封装了读缓冲区和写缓冲区,因此可以不用关注具体读写事件的差异。进一步管理读写事件,会提供三个回调:读回调、写回调、事件回调。

evconnlistener

封装了accpet()。
这里介绍一下accept()出错返回-1,errno=ENFILE的情况。此时fd数量达到上限,无法再创建fd。有几种解决方案:
1.重新设置fd上限。之前介绍过,不再赘述。
2.预先创建一个空fd。在一开始通过socket()创建一个空fd,不与任何连接绑定,当fd达到上限时,先关闭这个fd,再创建一个新的fd作为clientfd,告诉对端连接已满,再关闭这个连接,再建个空fd。
3.自己限制连接数。自己设置一个限制,要求连接数不超过某个值,这个值应小于系统的限制。
0.注意不能使用边沿触发。如果accpet()返回-1,就不会从全连接队列中取出连接。虽然epoll确实不会因为连接到达而继续触发,但是如果关闭了一些fd,可以建立新连接了,而此时epoll却因为边沿触发不会再被触发,即使有新连接到达。

libevent主要接口

注意与epoll接口对应,方便理解。

event_base_new

struct event_base *event_base_new(void);

初始化 libevent。对应 epoll_create()。

event_new

创建事件,初始化event和相应的回调函数。

struct event * event_new(struct event_base *base, evutil_socket_t fd, short events, void (*cb)(evutil_socket_t, short, void *), void *arg);

event_set

设置事件。

void event_set(struct event *ev, evutil_socket_t fd, short events,void (*callback)(evutil_socket_t, short, void *), void *arg);

event_base_set

建立 event 与 event_base 的映射关系。

int event_base_set(struct event_base *eb, struct event *ev);

event_add

注册事件,包括时间事件。

int event_add(struct event *ev, const struct timeval *tv);

注意添加事件之前,需要先event_base_set()绑定,将事件绑定在管理器上。

event_del

注销事件。

int event_del(struct event *ev);

以上四个函数对应epoll_ctl()。

event_base_loop

进入事件循环。相当于epoll_wait()。

int event_base_loop(struct event_base *base, int flags);

libev

libev的队列

libev有多个队列:
注册队列:将IO事件放在里面。检测到事件后就放到就绪队列中。
就绪队列:包括IO事件、定时器事件。会在event_base_loop中()依次调用,会调用这些事件的回调函数,这些回调函数不能是阻塞函数,否则会影响其他IO的处理。
堆队列:把定时器放到这个最小堆中。

libev数据结构

libev只保留了最基础的数据结构:网络IO、定时器事件、信号事件,目标是成为unix系统中的工具集。

libev主要接口

#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)

初始化 watcher 的 fd/events/callback。

void ev_io_start(struct ev_loop *loop, ev_io *w);

把事件绑定到ev_loop(事件管理器,相当于event_base)中。

void ev_timer_start(struct ev_loop *loop, ev_timer *w);

把定时器事件绑定到事件管理器中。

int ev_run(struct ev_loop *loop, int flags);

开启事件循环,相当于epoll_wait()中的事件循环。
最后再提示一下,libev还封装了与libevent一样的接口,只不过里面是由libev实现的。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_65931372/article/details/123333095

智能推荐

常见编程语言_常见的编程语言-程序员宅基地

文章浏览阅读1.7w次,点赞4次,收藏9次。编程语言排行榜TIOBE排行榜是根据互联网上有经验的程序员、课程和第三方厂商的数量,并使用搜索引擎(如Google、Bing、Yahoo!)以及Wikipedia、Amazon、YouTube统计出排名数据,只是反映某个编程语言的热门程度,并不能说明一门编程语言好不好,或者一门语言所编写的代码数量多少。链接:https://www.tiobe.com/tiobe-index/2019年3月排..._常见的编程语言

php smarty 高级缓存技巧方法_id="basictpl-程序员宅基地

文章浏览阅读442次。cache是smarty区别于其他模板系统的一个很重要的地方:  1. 设置当前这个页面的缓存时间。  2. 设置当前这个页面的CacheID,模板编号可以使用“|”分组。  3. 判断当前页面有没有被缓存过,如果缓存过,则直接读取缓存文件,没有缓存或者缓存过期,则执行正常的逻辑查找数据,显示页面,同时生成缓存文件。1.配置cacheinclude("Smart_id="basictpl

C语言实现——快速排序_c语言快速排序程序实现。 要求:输入一组无序的数据a[]={4,7,1,5,3,8,2,6} 输出这-程序员宅基地

文章浏览阅读442次。快速排序(每次看到它我总会想起大一上学C语言的时候的二分法查找目标元素。。。)快速排序中的重要一员就是基准数,将它归位,使得归位后该数的左边都是小于它的数,右边都是大于它的数。此时得到的序列不一定有序,因为它的左边和右边的大小顺序是不一定的。然后再选择一个基准数,继续进行交换,归位。采用递归方式实现。有点怕递归。。。举个例子:假设现在有无序的一组数:4,2,8,7,6,9,10,1,3,5(也就是1-10),以第一个数作为基准数,然后从最后一个位置开始向前寻找比4小的数,找到后停止,再从第二个位置向后寻_c语言快速排序程序实现。 要求:输入一组无序的数据a[]={4,7,1,5,3,8,2,6} 输出这

一篇文章足够你学习ESP32,提供史上最全的ESP32教程(驱动/蓝牙/Wi-Fi/LVGL/Arduino...)-程序员宅基地

文章浏览阅读10w+次,点赞222次,收藏2.3k次。本文章目的:1)针对单片机外设做详细的教程,丰富个人技能吃,彻底从原理+应用来写外设2)给广大蓝牙爱好者提供蓝牙应用方面的教程(结合我们的蓝牙协议栈会事半功倍)蓝牙协议栈教程点击我3)给广大Wi-Fi爱好者提供Wi-Fi方面的教程(结合我们的Wi-Fi协议栈会事半功倍)Wi-Fi协议栈教程点击我4)给广大GUI爱好者提供LVGL方面的教程LVGL教程点击我5)把各个技能池组合起来,举一反三,做炫酷的实例应用教程内容:我们的内容包括但不限于:1)IDF基础介绍_esp32教程

【C++--04】实验报告:数组、指针及引用;冒泡排序与二维数组存储学生信息;_c++引用实验报告-程序员宅基地

文章浏览阅读2.1k次,点赞6次,收藏17次。目录一.实验目的:二.实验任务:三.实验内容:1.冒泡排序实验分析:2.冒泡排序实验代码:3.冒泡排序实验结果:4.二维数组实验分析:5.实验代码6.运行结果:四.实验总结:一.实验目的:掌握用指针及引用作参数编写程序的知识技能; 提高学习者面向对象程序开发工具的自学习能力; 掌握一维数组和二维数组的定义、赋值和输入输出的方法。 能..._c++引用实验报告

spring事务和mysql事务关系-程序员宅基地

文章浏览阅读1.3k次。2019独角兽企业重金招聘Python工程师标准>>> ..._mysql事务与spring中的事务的关系

随便推点

chrome浏览器对应版本driver驱动_118.0.5993.71对应的driver-程序员宅基地

文章浏览阅读1.3w次。chromedriver下载地址:https://npm.taobao.org/mirrors/chromedriver/_118.0.5993.71对应的driver

Easy Excel 字典映射_easyexcel字典转换-程序员宅基地

文章浏览阅读1.6k次,点赞2次,收藏6次。Easy Excel 字典映射_easyexcel字典转换

Linux UDP严重丢包问题的解决_linux iperf丢包怎么解决-程序员宅基地

文章浏览阅读3.2k次。本文转自 :http://blog.csdn.net/kingmax26/article/details/5252667测试系统在Linux上的性能发现丢包率极为严重,发210000条数据,丢包达110000之巨,丢包率超过50%。同等情形下Windows上测试,仅丢几条数据。形势严峻,必须解决。考虑可能是因为协议栈Buffer太低所致,于是先看看默认情况: sysctl -a_linux iperf丢包怎么解决

写给程序员的几点忠告-----金石良言_给程序员的忠告-程序员宅基地

文章浏览阅读1.2k次。记不清,是从哪看到的了. 但 一直以来,感觉十分有道理.1. 好好规划自己的路,不要跟着感觉走.2. 可以做技术的,切不可沉湎于技术.3. 不要去做技术高手,只去做综合素质高手.4. 多交"三交九流"的朋友.5. 知识涉猎不仅要专,还一定要广。6. 抓住时机向技术管理或市场销售方面转变。7。逐渐克服自己的心理弱点和性格缺陷。8。工作的同时要为以后作准备,建立自己的工作的环境。9。学会善于推销_给程序员的忠告

android 程序怎么用python_android程序员python学习之路-程序员宅基地

文章浏览阅读165次。1年半android经验,初次接触python,学了几天,相见恨晚,迫不及待的写了这篇记录下。python新手,请多见谅。其实也不是最近才接触Python,大四上有一门计算机性能相关的课各种算法、工具要求用python写,不过当时太懒了,全用java写的。导致毕业一年多了,现在每天忙碌的工作之余,晚上这个点左右挤时间出来学,算是"自我救赎"吧,哈哈。其实第一感觉python只是简单,没有那么吸引人..._做android有必要学习python吗

docker 搭建本地 coredns 服务器_docker coredns-程序员宅基地

文章浏览阅读5.2k次。CoreDNS是一款灵活可扩展的 DNS 服务器,并且基于插件架构,具有强大的模块化能力。其快速,简单,可扩展等特性也非常受人欢迎。_docker coredns