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

看到没,这就是C语言的恶心指出,尼玛找个定一点都要用全局搜索字符,才找到这个宏。

好吧,看它都做了写神马东东:

ev_init ((ev), (cb));就是把watcher进行初始化,把回调设置进去;

ev是神马玩意呢,就是ev_io:

/* invoked when fd is either EV_READable or EV_WRITEable */
/* revent EV_READ, EV_WRITE */
typedef struct ev_io
{
EV_WATCHER_LIST (ev_io)//watcher链表 int fd; /* ro */
int events; /* ro */
} ev_io;

ev_io_set ((ev),(fd),(events));就是把watcher的fd 和 events分别进行设置。

ok。举个例子:

#include <ev.h>
#include <stdio.h> // for puts // every watcher type has its own typedef'd struct
// with the name ev_TYPE
ev_io stdin_watcher; // all watcher callbacks have a similar signature
// this callback is called when data is readable on stdin
static void stdin_cb (EV_P_ ev_io *w, int revents)//时间回调
{
puts ("stdin ready");
// for one-shot events, one must manually stop the watcher
// with its corresponding stop function.
ev_io_stop (EV_A_ w); // this causes all nested ev_run's to stop iterating
ev_break (EV_A_ EVBREAK_ALL);
} int main (void)
{
// use the default event loop unless you have special needs
struct ev_loop *loop = EV_DEFAULT; // initialise an io watcher, then start it
// this one will watch for stdin to become readable
ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ);
ev_io_start (loop, &stdin_watcher); // now wait for events to arrive
ev_run (loop, 0); // break was called, so exit
return 0;
}

  ok,这样,通过ev_io_init就把我们关注的事件和回调放进ev_io;

但这时候还与loop木有关系哇,是的,看后面一句调用:ev_io_start

不过貌似libev版本升级啦,这个函数签名都改版了:

void noinline ev_io_start (EV_P_ ev_io *w) EV_THROW
{
int fd = w->fd;

  //如果已经是active的就返回
if (expect_false (ev_is_active (w)))
return; assert (("libev: ev_io_start called with negative fd", fd >= ));
assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); EV_FREQUENT_CHECK; ev_start (EV_A_ (W)w, );
array_needsize (ANFD, anfds, anfdmax, fd + , array_init_zero);
wlist_add (&anfds[fd].head, (WL)w); /* common bug, apparently */
assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w)); fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);
w->events &= ~EV__IOFDSET; EV_FREQUENT_CHECK;
}
其中有个函数:
inline_speed void ev_start (EV_P_ W w, int active)
{
pri_adjust (EV_A_ w);//设置优先级,其中会check io的pri,然后把check后的pri设置进去,如果我们默认pri=0,其实调用前后木有神马变化
w->active = active;//active=1,表示设置为active
ev_ref (EV_A);//loop里的activecnt进行++,就是对io进行统计吧
} wlist_add (&anfds[fd].head, (WL)w);//对一个fd 添加需要的事件列表,不过还木有看见过对一个fd添加很多事件的情况

/*****************************************************************************/
/* singly-linked list management, used when the expected list length is short */

inline_size void wlist_add (WL *head, WL elem)//很明显是头插法,把当前watecher插到list头部,然后替换

{
elem->next = *head;
*head = elem;
}

ok,最后一个函数:

/* something about the given fd changed */
inline_size void fd_change (EV_P_ int fd, int flags)
{
unsigned char reify = anfds [fd].reify;
anfds [fd].reify |= flags; if (expect_true (!reify))
{
++fdchangecnt;
array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
fdchanges [fdchangecnt - ] = fd;
}
}

暂时没搞懂上面的函数是搞神马的,之后再看,或者明白的网友看到了,给讲下啊

libev ev_io_init学习的更多相关文章

  1. Libev库学习

    Libev库学习 https://www.cnblogs.com/wunaozai/p/3950249.html Libev库学习(1)https://www.cnblogs.com/wunaozai ...

  2. Socket网络编程--Libev库学习(1)

    这一节是安装篇. Socket网络编程不知不觉已经学了快两个月了.现在是时候找个网络库学学了.搜索了很多关于如何学网络编程的博客和问答.大致都是推荐学一个网络库,至于C++网络库有那么几个,各有各的好 ...

  3. Socket网络编程--Libev库学习(3)

    这一小节继续讲解各个观察器(Watcher). 上一小节已经讲解了ev_io(IO可读可写观察器),ev_stat(文件属性变化观察器),ev_signal(信号处理观察器),ev_timer(定时器 ...

  4. Socket网络编程--Libev库学习(2)

    这一小节讲各个观察器(Watcher) 在libev下面watcher相当于EventHandler这么一个概念,通常里面会绑定fd回调函数以及我们需要关注的事件. 然后一旦触发事件之后会触发我们使用 ...

  5. libev学习笔记

    转 libev的使用--结合Socket编程 作者:cxy450019566 之前自己学过一些libev编程的基础,这次写压测刚好用上了,才算真正动手写了些东西,在这里做一些总结.写这篇文章是为了用浅 ...

  6. 【转载】使用事件模型 & libev学习

    参考这篇文章: http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/ 这里面使用的是 libev ,不是libevent Nodejs就是采用 ...

  7. libev事件库学习笔记

    一.libev库的安装 因为个人的学习环境是在ubuntu 12.04上进行的,所以本节仅介绍该OS下的安装步骤. 使用系统工具自动化安装: sudo apt-get install libev-de ...

  8. Libev学习笔记2

    这一节根据官方文档给出的简单示例,深入代码内部,了解其实现机制.示例代码如下: int main (void) { struct ev_loop *loop = EV_DEFAULT; ev_io_i ...

  9. Libev学习笔记1

    和Libevent相似,Libev是一个高性事件驱动框架,据说性能比Libevent要高,bug比Libevent要少.Libev只是一个事件驱动框架,不是网络库,因为它的内部并没有任何socket编 ...

随机推荐

  1. sublime同步文件与siderbar

    有时候,打开了sider bar,想和Eclipse.idea一样,每打开一个tab,就可以在左侧的sider bar 目录上面看到我当前的位置,于是找到了一个插件. SyncedSideBar 安装 ...

  2. Android Studio中关于9-patch格式图片的编译错误

    最近在编译Android Studio开发的项目中在使用了9宫图后出现了编译错误,尝试了多种方法未能解决,最后仔细查看出错的日志发现,居然是图片的原因,图片中包含有alpah通道所以在执行app:me ...

  3. C#.NET常见问题(FAQ)-如何判断某个字符是否为汉字

    字符强制转换成int可以判断字符数值大小,在下面所示范围内的就是中文   此外还可以判断是否是数字或者字母,用char.IsLetter和char.IsDigit方法   从先这个范例可以看出,中文也 ...

  4. ArcGIS鼠标滚轮方向之ArcMap篇

    ArcMap中地图缩放滚轮方向与我们常用的AutoCAD.在线地图等相反.ArcMap默认滚轮向上缩小,向下放大,曾经引起过多位用户的不满.好在ArcMap提供个性化设置. 打开ArcMap菜单栏-自 ...

  5. Ubuntu IntelliJ IDEA 注冊碼與Gradle相關

    一.Ubuntu IntelliJ IDEA 注冊碼 在线免费生成IntelliJ IDEA 15.0(16.+)注册码 注冊參考:https://www.iteblog.com/idea/ 依次选择 ...

  6. C++ 第四课:ASCII 码表

    下面的 ASCII 码表包含数值在0-127之间的字符的十进制.八进制以及十六进制表示. 十进制 八进制 十六进制 字符 描述 0 0 00 NUL   1 1 01 SOH start of hea ...

  7. Mongodb3安装授权

    (1) mongodb 官网下载解压包mongodb-win32-x86_64-3.0.7.zip解压释放在d盘,目录为mongodb,接下来手动创建data文件夹和log文件夹分别用于存放数据和日志 ...

  8. JAVA调用SHELL事例

    以往一直都是crontab+shell调用java程序,最近需要反过来,使用java调用shell程序,实现定时管理,今天总结一下. 基础内容: java的java.lang.Runtime类提供了e ...

  9. 算法笔记_217:黑洞数(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 任意一个5位数,比如:34256,把它的各位数字打乱,重新排列,可以得到一个最大的数:65432,一个最小的数23456.求这两个数字的差,得:41 ...

  10. Sql server中依据存储过程中的部分信息查找存储过程名称的方法【视图和Function】

    1.查询的语句: select a.id,b.name,a.*,b.* from syscomments a join sysobjects b on a.id=b.id where b.xtype= ...