创作人QQ:851301776,邮箱:lfr890207@163.com,欢迎大家一起技术交流,本博客主要是自己学习的心得体会,只为每天进步一点点!
个人座右铭: 1.没有横空出世,只要厚积一定发。 2.你可以学历不高,你可以不上学,但你不能不学习。
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定时器使用四叉树,定时器很准
aclocal libtoolize --force autoheader automake --add-missing autoconf ./configure && make && make install
(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);
(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)
win10升级使用WSL2,可以支持完全版的Linux子系统,可以安装VScode远程调试。
win10升级使用WSL2方法:Win10 升级使用 WSL2_SpeculateCat-CSDN博客
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 使用libevent做的
Memcached 主要是由1个accept线程和n(CPU核数)个work线程组成。accept和每个work线程都有一条管道,accpet线程写,work线程读。
accept线程在队列中加入节点,work线程从队列中读取。
每个work线程都是独立操作libevent。