特征
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;
分析了如下几个宏: