libev-简单使用解析

转自:http://www.ittomato.com/?p=45

Anatomy of a watcher

假如我要等待STDIN是否可读,你可以createy一个ev_io的watcher,例如

01 staticvoidmy_cb (structev_loop *loop, ev_io *w,intrevents)
02 {//回调函数
03
04 ev_io_stop (w);
05
06 ev_break (loop, EVBREAK_ALL);
07
08 }
09 structev_loop *loop = ev_default_loop (0);
10 //创建io的watcher对象
11 ev_io stdin_watcher;
12 ev_init (&stdin_watcher, my_cb);
13 ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ);
14 ev_io_start (loop, &stdin_watcher);
15 ev_run (loop, 0);

每个watcher结构都必须调用ev_init进行初始化,同时指定一个回调函数。

—————————————————————————————————–

1 ev_init (ev_TYPE *watcher, callback)

当watcher捕捉到event时候,会自动调用回调函数(ev_init的第2个参数)。通过调用ev_io_set可以自定义watcher的属性。

一般初始化一个watcher,只须2步:

1 ev_io w;
2 ev_init (&w, my_cb);
3 ev_io_set (&w, STDIN_FILENO, EV_READ);

当然还有更简单的办法,直接调用

1 ev_io_init(&w, my_cb,stdin_fileno, evread);

查看了ev_io_init的源代码,如下:

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

可见,ev_io_init是个宏,整合了ev_init和ev_io_set的宏,ev_io_init等价于:

1 ev_init((ev), (cb));
2 ev_io_set((ev), (fd), (events));

其他的ev_TYPE_init()函数的实现也类似ev_io_init(),有兴趣可参考下源代码。(TYPE可以是Timer,child,fork,cleanup等等)。ev_io_set必须在ev_init使用后才可以使用;但是ev_TYPE_set可以在ev_init调用后的任何时候再调用!
—————————————————————————————————–

callback回调函数:

必须的格式:

1 void(*)(structev_loop *loop, ev_TYPE *watcher,intrevents);

例如上面简单的回调函数,删除掉watcher,再break出loop循环

1 staticvoidmy_cb(structev_loop *loop, ev_io *w,intrevents);
2 {
3
4 ev_io_stop(w);
5
6 ev_break(loop, EVBREAK_ALL);
7
8 }

—————————————————————————————————–

1 ev_TYPE_start (loop, ev_TYPE *watcher)

只有激活的watcher才能收到事件event,ev_TYPE_start,则是激活watcher的函数,例如,激活io事件:

1 ev_io_start(loop, &w);
2 ev_TYPE_stop (loop, ev_TYPE *watcher)

同理,撤销watcher:

1 ev_io_stop(loop, &w);
2 ev_run (loop, ev_TYPE *watcher)

源代码的声明如下:

1 EV_API_DECLvoidev_run (EV_P_intflags EV_CPP (= 0));

这代码,还起来有点羞涩难懂!一个函数声明,就用了这么多宏。每个宏代表什么?而且函数的参数竟然没有没有逗号分隔开,是一个参数,还是多个?带着这些问题,我们来一步一步跟进源代码!

01 EV_API_DECL
02
03 #ifdef EV_API_STATIC
04
05 # define EV_API_DECL static
06
07 #else
08
09 # define EV_API_DECL extern
10
11 #endif

即,EV_API_DECL 等价于static 或者extern

1 EV_P_
2
3 # define EV_P struct ev_loop *loop
4
5 # define EV_P_ EV_P,

即,EV_P_ 等价于struct ev_loop *loop,

01 EV_CPP
02
03 #ifdef __cplusplus
04
05 # define EV_CPP(x) x
06
07 #else
08
09 # define EV_CPP(x)
10
11 #endif

即,EV_CPP(x)等价于 x或者空
假设已经定义了EV_API_STATIC,__cplusplus,那么上面ev_run函数

1 EV_API_DECLvoidev_run (EV_P_intflags EV_CPP (= 0));

等价于:

1 staticvoidev_run(structev_loop *loop,intflags=0);

变形剖析后的ev_run函数就符合正常代码规格了!

其他的函数,例如ev_io_start,ev_timer_start等的声明也不外乎用了宏!

libev的库使用了大量的宏定义,本文到目前为止,只简单介绍了:

callback,watcher,ev_io,ev_init,ev_io_set,ev_io_start,ev_run各个函数的简单使用!大致了解了libev库的使用方法

1、声明loop

2、声明watcher

3、声明ev_io

4、初始化ev_init

5、设置ev_io_set,(和步骤4一起调用可用函数ev_io_init()替代)

6、把watcher加入到loop的ev_io_start

7、最后运行ev_run

简单的几行代码,使用起来方便快捷!

下一节,再更深入了解上面各个函数的具体实现!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值