libev是一个用C语言编写的轻量级的事件驱动库,支持多种IO复用接口。
IO接口有:select,poll,epoll,kqueue等
支持的事件:
ev_io; //IO读写 ev_stat; //文件属性 ev_signal;//信号 ev_timer;//定时器 ev_periodic;//绝对定时器 ev_child;//子进程 ev_fork;//fork事件 ev_cleanup;//ev_loop退出触发 ev_idle;//ev_loop空闲触发 ev_embed;//嵌入后台循环 ev_prepare;//ev_loop之前事件 ev_check;//ev_loop之后事件 ev_async;//线程间异步事件
libev把事件封装在监视器 watcher 中,watcher是一个结构体,里面保存着与事件相关的信息,包括事件的属性等。
通过注册 watcher 并指定其回调函数,再将监视器注册驱动器即可使用。
EV_P,EV_P_,EV_A,EV_A_
以下代码来自 ev.h <171>
/* support multiple event loops? */ #if EV_MULTIPLICITY struct ev_loop; # define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */ # define EV_P_ EV_P, /* a loop as first of multiple parameters */ # define EV_A loop /* a loop as sole argument to a function call */ # define EV_A_ EV_A, /* a loop as first of multiple arguments */ # define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */ # define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */ # define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */ # define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */ #else # define EV_P void # define EV_P_ # define EV_A # define EV_A_ # define EV_DEFAULT # define EV_DEFAULT_ # define EV_DEFAULT_UC # define EV_DEFAULT_UC_ # undef EV_EMBED_ENABLE #endif
EV_MULTIPLICITY 显然是一个条件,字面意思 多个事件
表明当允许多个ev_loop示例存在时
ev_loop是主循环,在前几篇的例子中,都是声明了:
ev_loop* main_loop;
看#if部分,有一些宏定义的很奇葩。
# define EV_P struct ev_loop *loop ;//用EV_P代替struct ev_loop *loop //也就是说,可以这样写: void fun(EV_P, ev_io io_w); # define EV_P_ EV_P, ;//这个定义要特别注意逗号 ‘,’ //也就是说,加上逗号,可以这样写: void fun(EV_P_ ev_io io_w); //没错,就是省了一个逗号,看起来更像老油条而已
其他部分类似。
对于#else的部分,则是正常的宏定义,第一个参数就是替换为空,即删除
libev定义事件很好懂,都是形如 ev_xxx,xxx是事件名,如ev_io,ev_timer
因为C语言是没有类的概念的,那么又想实现多态怎么办呢?
多态的概念不再赘述,而C要实现,无非就是用一些杂七杂八的struct和一些宏定义来实现。
这些监视器里面都包含同一个宏 EV_WATCHER(type)
这个宏的具体定义如下:
/* shared by all watchers */ #define EV_WATCHER(type) \ int active; /* private */ \ int pending; /* private */ \ EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */ #define EV_WATCHER_LIST(type) \ EV_WATCHER (type) \ struct ev_watcher_list *next; /* private */ #define EV_WATCHER_TIME(type) \ EV_WATCHER (type) \ ev_tstamp at; /* private */
看懂这些宏就需要一些#define的高级知识了。
先不用管这三行是什么意思
EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */
可以理解,EV_WATCHER(type)里面包含 五项:
int active; /* private */ \ int pending; /* private */ \ EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (type) /* private */
再看具体的监视器,watcher的定义:
/* base class, nothing to see here unless you subclass */ typedef struct ev_watcher { EV_WATCHER (ev_watcher) } ev_watcher;
这段代码头上注释:/* base class, nothing to see here unless you subclass */,可见,这是在抽象实现类,所以理解源码,必然要学会面向对象的思想。
可见ev_watcher里面包含EV_WATCHER(type),其实两者合一,就是如下:
typedef struct ev_watcher { int active; int pending; EV_DECL_PRIORITY /* private */ \ EV_COMMON /* rw */ \ EV_CB_DECLARE (ev_watcher) /* private */ } ev_watcher;
具体后三位是表示什么,还要找到具体的宏定义。
第一个宏定义在此:
#if EV_MINPRI == EV_MAXPRI # define EV_DECL_PRIORITY #elif !defined (EV_DECL_PRIORITY) # define EV_DECL_PRIORITY int priority; #endif
又出来了两个宏 EV_MINPRI,EV_MAXPRI,先不管,这个语句的读法就是if-else if-else
总归,EV_DECL_PRIORITY就是 int priority;
不细说了,直接上code
#ifndef EV_COMMON # define EV_COMMON void *data; #endif #ifndef EV_CB_DECLARE # define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents); #endif
所以最后,那个watcher就是传说中的!:这个东西,就是一个结构体里面定义了一些内容而已。
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;
ok,分析完watcher监视器的内容,那个EV_WATCHER还附带一个 LIST和TIME的宏定义,再来分析一下,ev_watcher里同样也配套定义了list和time部分,如下:
/* base class, nothing to see here unless you subclass */ typedef struct ev_watcher_list { EV_WATCHER_LIST (ev_watcher_list) } ev_watcher_list; /* base class, nothing to see here unless you subclass */ typedef struct ev_watcher_time { EV_WATCHER_TIME (ev_watcher_time) } ev_watcher_time;
根据上述的例子,展开,就是如下:
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 struct ev_watcher_time { int active; int pending; int priority; void *data; void (*cb)(struct ev_loop *loop, struct ev_watcher_time *w, int revents); ev_tstamp at; } ev_watcher_time;
分析了如下几个宏: