Linux libevent和libev 一

创作人QQ:851301776,邮箱:lfr890207@163.com,欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!

个人座右铭: 1.没有横空出世,只要厚积一定发。 2.你可以学历不高,你可以不上学,但你不能不学习。

一、libevent和libev简述

libevent和libev都是C语言实现的异步事件库,通过注册异步事件,库检测事件触发,从而库根据发生事件的先后顺序,调用响应回调函数进行处理。

事件包括:网络io事件,定时事件。信号事件

事件循环:等待并分发事件,用于管理事件

libevent和libev主要封装了异步事件库与操作系统的交互,让使用者不用关注平台的差异,只需要关注事件的具体处理

libevent和libev对Linux支持比较好,但是对window是支持都比较差,libuv对windows的支持比较好,libuv是在libev的基础上封装了iocp,node.js基于libuv。

二、区别

从设计理念出发,libev 是为了改进 libevent 中的一些架构决策,例如,全局变量的使用使得在多

线程环境中很难安全地使用 libevent,watcher 的数据结构设计太大,因为它们将 I/O、时间和信

号处理放在一个结构体中,额外的组件如 http 、dns、openssl, 服务器由于实现质量差以及由

此产生的安全问题,计时器不精确,不能很好地处理时间事件。

libev 通过不使用全局变量,而是对所有回调函数传参的方式传递上下文;并且根据不同事件类型

构建不同的数据结构,这样以来减低事件的耦合性;

libev 小而高效;只关注事件处理;

libev定时器使用四叉树,定时器很准

三、libevent的主要接口

1.编译

aclocal 
libtoolize --force 
autoheader 
automake --add-missing 
autoconf 
./configure && make && make install

2.主要接口

(1)初始化libevent

struct event_base *event_base_new(void);

(2)创建事件

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

(3)设置事件

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

(4)建立event和event_base的映射关系

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

(5)注册事件

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

(6)注销事件

int event_del(struct event *ev);

(7)进入事件循环

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

四、libev

1.主要接口

(1)初始化watcher

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

(2)注册并绑定io watcher到ev_loop

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

(3)注册并绑定 timer watcher 到 ev_loop

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

(4)开启ev_loop的事件循环

int ev_run(struct ev_loop *loop, int flags)

五、window升级

win10升级使用WSL2,可以支持完全版的Linux子系统,可以安装VScode远程调试。

win10升级使用WSL2方法:Win10 升级使用 WSL2_SpeculateCat-CSDN博客

六、accept返回-1问题

errno=EMFILE,表示fd达到上限,解决办法如下:

(1)先创建空的fd,然后关闭空fd,在创建clientfd,然后关闭空clientfd,在创建空的fd

int NULL_fd;
if(errno == EMFILE)
{
    NULL_fd = open("/dev/null", O_RDONLY| O_CLOEXEC);
    close(NULL_fd);
    NULL_fd = accept(listenfd, NULL, NULL);
    close(NULL_fd);
    NULL_fd = open("/dev/null", O_RDONLY| O_CLOEXEC);
}

(2)限制最大连接数量

七、Memcached 基础介绍

  1. Memcached 使用libevent做的

  2. Memcached 主要是由1个accept线程和n(CPU核数)个work线程组成。accept和每个work线程都有一条管道,accpet线程写,work线程读。

  3. accept线程在队列中加入节点,work线程从队列中读取。

  4. 每个work线程都是独立操作libevent。

上一篇:libevent(十)bufferevent filter 事件消息输入输出过滤


下一篇:Hadoop离线 day17 日志采集框架Flume和工作流调度器azkaban