libev源码分析(二)---ev_io

版权声明:凡本人原创,转发请注明出处,谢谢! https://blog.csdn.net/qq_41248872/article/details/83931704

 1.ev_io结构

typedef struct ev_io{
  
  EV_WATCHER_LIST (ev_io)
 
  int fd;    /* 文件描述符 */
  int events; /* 事件类型 */

} ev_io;

2 . 作用
ev_io是我们最常用的一个watcher。因为项目中,时间循环的应用场景大部分也都集中在io的读写方面。

从ev_io的声明中我们可以看到它继承了WATCHER_LIST,并且有两个新字段,fd和events。不难理解fd就是用来保存所监听的文件描述符的,而events则是记录了我们所要监听的时间,一般为读、写。

3 .相关函数

 ev_init (ev_io *ev,callback)  ; 

 ev_io_set(ev_io *ev, int fd, int events);

 ev_io_init(ev_io *ev, callback,int fd, int events);

ev_io_init等价于调用ev_init,再调用ev_io_set。其功能是将回调函数、文件描述符以及所监听的事件绑定到watcher上。

根据实践经验,我觉得最好还是少调用ev_io_init。因为ev_init只能对watcher执行一次,但我们却可能经常需要重置watcher,这时如果我们再次调用ev_io_init而不是调用ev_io_set对watcher进行重置,就可能会使程序core掉。我会在以后提到这个问题。

ev_io_start(EV_P_ ev_io * w);

ev_io_start的作用就是将已经初始化好的watcher绑定到事件监听主循环ev_loop上。在这个过程中:

l  首先会检查正确性,在这里用到了一个宏EV_FREQUENT_CHECK,其具体内容就是进行各种检查,就不仔细讨论了。

l  调用ev_start将监视器active置为启动,同时设置优先级等。

l  调用array_needsize检查anfds的大小是否足够放入新的fd,如果不够realloc。

l  调用wlist_add将fd插入anfds中。

l  最后调用fd_change注册行为改变的函数,改函数把所有新的fd或者所监听的事件有改变的fd存放到fdchanges数组中,在适当的时候调用底层事件模型进行修改。

ev_io_stop(EV_P_ ev_io * w);

ev_io_stop的作用正好与ev_io_start相反,就是把watcher从ev_loop中去除。起流程基本如下:

l  首先从pendings中清楚watcher对应的即将被触发的事件。

l  调用EV_FREQUENT_CHECK进行检查。

l  调用wlist_del从anfds中清除相关fd。

l  调用ev_stop将watcher的active置为0。

l  调用fd_change注册fd行为变化。
 

猜你喜欢

转载自blog.csdn.net/qq_41248872/article/details/83931704
今日推荐