1. ev_watcher和ev_loop
ev_watcher:
libev中所有事件的基础类型ev_watcher,所有的事件都可以通过(W)watcher转换成ev_watcher,大写的W在libev定义的是ev_watcher *。抽象出ev_watcher作用是所有的watcher都可以共用ev_start、ev_stop函数
下面用ev_TYPE表示ev_io、ev_timer、ev_async各种watcher类型的通用形式。各种类型的ev_TYPE都继承自ev_watcher,还有形如ev_TYPE_init、ev_TYPE_start、ev_TYPE_stop。
typedef struct ev_watcher {
int active;
int pending;
int priority;
void *data;
void (*cb)(struct ev_loop *loop, struct ev_watcher *w, int revents);
} ev_watcher;
typedef ev_watcher *W
active: 标记当前的watcher有没有active,执行ev_TYPE_start之后watcher算是active
pending: 大于0表示当前的watcher有时间触发,当前的watcher正在loop->pendings队列里(loop->pendings队列是一个数组),pending的值是loop->pendings队列数组中的下标。 priority: watcher的优先级
data: 在初始化watcher时,上层应用用于保存cb回调时候将要用到的数据或结构体pending队列数组中的下标。
cb: 对pending状态的watcher执行的回调函数。
ev_loop:
在一个事件循环的周期里,ev_loop保存我们所有watcher所需的信息。包含各种watcher链表、数组、执行的状态信息,epoll相关的数据结构,时间等。
loop执行流程:
2. ev_io
和ev_io相关的结构体
// ev_watcher_list可以说成是继承ev_watcher,ev_watcher_list是为了有多个watcher的时候,可以把ev_watcher用链表的时候连起来
// 抽象出ev_watcher_list作用是所有的watcher都可以共用WL链表,包括wlist_add、wlist_del的操作
typedef struct ev_watcher_list {
int active;
int pending;
int priority;
void *data;
void (*cb)(struct ev_loop *loop, struct ev_watcher_list *w, int revents);
struct ev_watcher_list *next;
} ev_watcher_list;
typedef ev_watcher_list *WL;
// ev_io继承ev_watcher_list,ev_io事件链表中真正保存的是ev_io
typedef struct ev_io {
int active;
int pending;
int priority;
void *data;
void (*cb)(struct ev_loop *loop, struct ev_io *w, int revents);
struct ev_watcher_list *next;
int fd;
int events;
} ev_io;
// 用于保存fd 事件信息的结构,loop初始化的时候会初始化一个ANFD的数组,每个ANFD表示一个fd对应的这个fd的所有事件信息
typedef struct {
WL head; // 每个fd可以有多个事件
unsigned char events; // 事件类型
unsigned char reify;
unsigned char emask;
unsigned char cdel;
unsigned int egen;
} ANFD;
ev_loop结构中对应ev_io关键的变量
ANFD *anfds; // 每个fd对应一个ANFD[fd]结构,添加的watcher都保存在对应的anfds[fd]结构中。
ANPENDING *pendings [5]; //
struct epoll_event *epoll_events; //
int *fdchanges; // 执行ev_io_start用fdchanes记录fd对应的anfds[fd]有修改。
ev_io watcher添加、执行、删除
1)向fd添加watcher:
ev_io_init // 只做一些初始化的操作
ev_io_start // 添加的新的事件,没有做真正的事件监听的改变(没执行epoll_ctl)
在ev_io_start会执行
wlist_add (&((loop)->anfds)[fd].head, (WL)w); // 把watcher加到anfds[fd]对应的事件链表中
fd_change (loop, fd, ((w->events & EV__IOFDSET) | 1)); // 把fd添加到fdchanges数组里
。。。 中间可能会执行很多操作,可以停掉事件等等 。。。
在每次epoll_wait之前执行fd_reify(loop) // 这里才会真正调用epoll_ctl
在fd_reify中会遍历fdchanges数组,把对fd事件的修改通过调用epoll_modify来做真正的修改
2)唤醒watcher:执行loop->backend_poll调用epoll_wait,有read或者写的事件返回
根据epoll_wait返回的fd,找到anfd,遍历anfd->head(head是保存我们加入的事件链表),如果匹配返回的事件的类型,把watcher加入到pendings数组里
3)回调watcher:执行loop->invoke_cb(对应ev_invoke_pending函数)
在invoke_cb中遍历loop->pendings数组,找到对应的watcher进行回调(执行watcher->cb)
3)删除watcher:执行ev_io_stop
删除loop->anfds[fd]->head链表中对应的watcher,把fd添加到fdchanges数组里,等待下次执行fd_reify(loop)真正删除
分享到:
相关推荐
libev4-4.15-7.1.x86_64.rpm percona-xtrabackup-2.1.3-608.rhel6.x86_64 安装需要的包
libev是高性能事件循环/事件模型的网络库,并且包含大量新特性,除了提供了基本的三大类事件(IO事件、定时器事件、信号事件)支持外还提供了周期事件、子进程事件、文件状态改变事件等多个事件的支持
离线安装包,亲测可用
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
libhv libev libuv libevent 2020-08-28 最新源代码。这是几个经典的跨平台网络开发库
安装xtrabackup必须要用到的一个依赖,分享给大家,分享给大家。
官方离线安装包,亲测可用
官方离线安装包,亲测可用
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
官方离线安装包,亲测可用。使用rpm -ivh [rpm完整包名] 进行安装
官方离线安装包,亲测可用
离线安装包,亲测可用
离线安装包,亲测可用
官网已经无法下载,备份出来分享给大家,libev是libevent之后的一个事件驱动的编程框架
1、编译libev 解压 ./configure --prefix=/opt/a40i/libev --host=arm-linux-gnueabihf- CC=arm-linux-gnueabihf-gcc make make install 2、编译rtty 解压rtty cd build cmake ../ -DCMAKE_INSTALL_PREFIX=/opt/a40...
rabbitmq安装依赖包,libev是libevent之后的一个事件驱动的编程框架,其接口和libevent基本类似。据官方介绍,其性能比libevent还要高,bug比libevent还少。
libev-4.15 最新代码
离线安装包,亲测可用