libev ev_io_init学习
#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学习的更多相关文章
- Libev库学习
Libev库学习 https://www.cnblogs.com/wunaozai/p/3950249.html Libev库学习(1)https://www.cnblogs.com/wunaozai ...
- Socket网络编程--Libev库学习(1)
这一节是安装篇. Socket网络编程不知不觉已经学了快两个月了.现在是时候找个网络库学学了.搜索了很多关于如何学网络编程的博客和问答.大致都是推荐学一个网络库,至于C++网络库有那么几个,各有各的好 ...
- Socket网络编程--Libev库学习(3)
这一小节继续讲解各个观察器(Watcher). 上一小节已经讲解了ev_io(IO可读可写观察器),ev_stat(文件属性变化观察器),ev_signal(信号处理观察器),ev_timer(定时器 ...
- Socket网络编程--Libev库学习(2)
这一小节讲各个观察器(Watcher) 在libev下面watcher相当于EventHandler这么一个概念,通常里面会绑定fd回调函数以及我们需要关注的事件. 然后一旦触发事件之后会触发我们使用 ...
- libev学习笔记
转 libev的使用--结合Socket编程 作者:cxy450019566 之前自己学过一些libev编程的基础,这次写压测刚好用上了,才算真正动手写了些东西,在这里做一些总结.写这篇文章是为了用浅 ...
- 【转载】使用事件模型 & libev学习
参考这篇文章: http://www.ibm.com/developerworks/cn/linux/l-cn-edntwk/ 这里面使用的是 libev ,不是libevent Nodejs就是采用 ...
- libev事件库学习笔记
一.libev库的安装 因为个人的学习环境是在ubuntu 12.04上进行的,所以本节仅介绍该OS下的安装步骤. 使用系统工具自动化安装: sudo apt-get install libev-de ...
- Libev学习笔记2
这一节根据官方文档给出的简单示例,深入代码内部,了解其实现机制.示例代码如下: int main (void) { struct ev_loop *loop = EV_DEFAULT; ev_io_i ...
- Libev学习笔记1
和Libevent相似,Libev是一个高性事件驱动框架,据说性能比Libevent要高,bug比Libevent要少.Libev只是一个事件驱动框架,不是网络库,因为它的内部并没有任何socket编 ...
随机推荐
- 原生JS实现new方法、new一个对象发生的四部、new里面常用的优先级
一.js中new一个对象的过程 首先了解new做了什么,使用new关键字调用函数(new ClassA(…))的具体步骤: 1.创建一个新对象: var obj = {}; 2.设置新对象的const ...
- Android -- Camera2(Android5.0)
Camera2 Camera2是Android5.0中的其中一个新的特性,新的API.与原来的camera API相比,不同之处在于: 原生支持RAW照片输出 突发拍摄模式 制约拍照速度的不再是软件而 ...
- 【机器学习】Logistic Regression 的前世今生(理论篇)
Logistic Regression 的前世今生(理论篇) 本博客仅为作者记录笔记之用,不免有非常多细节不正确之处. 还望各位看官能够见谅,欢迎批评指正. 博客虽水,然亦博主之苦劳也. 如需转载,请 ...
- 彻底解决 Intellij IDEA 卡顿 优化笔记,重要的快捷键
由于工作中经常出现分支各种切换,使用Eclipse便不再像以前那么舒服了,不停的修改工作空间,每次修改完工作空间又是一堆一堆的个性化设置,来回的切换,真的很累.我们做软件的,怎么能不去尝试新鲜的呢,毕 ...
- GB2312码表
GB2312码表 code +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F A1A0 . . · ˉ ˇ ¨ " 々 — - | … ‘ ’ ...
- C# 动态解析表达式
需求 我们很难捉摸用户的思维,即使使用非常正式的文档规范某些数据的定义.结果的标准等,也不能抵挡住用户不断变化的需求,但他们有个万变不离的东西——你做这个东西要是万能的,即输入参数类型.个数等发生改变 ...
- mysql 表分区 查看表分区 修改表分区
原文地址:http://blog.csdn.net/feihong247/article/details/7885199 一. mysql分区简介 数据库分区 数据库分区是一种物理数据库设 ...
- jstl函数的使用
1.fn:contains()和fn:containsIgnoreCase() fn:contains()函数用于确定一个字符串是否包含指定的子串. fn:containsIgnoreCase()函数 ...
- Lintcode: Add Two Numbers
C++ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * List ...
- 使用Spring框架入门一:基于XML配置的IOC/DI的使用
一.Spring框架 1.方法一:逐项导入基础依赖包: spring-core.spring-beans.spring-context.spring-expression 2.方法二:最简洁的导入,直 ...