libev是一个开源库,实现了一个reactor模式事件驱动任务调度库。代码非常精简,包含所有实现的.c文件只有不到5000行。
支持的事件类型:
ev_io
ev_timer
ev_periodic
ev_signal
ev_child
ev_stat
ev_idle
ev_prepare  and ev_check
ev_embed
ev_fork
ev_cleanup
ev_async
常用的事件类型:
ev_io,io就绪事件
ev_timer,定时器事件
ev_signal,信号事件
官方使用例子
ev_io
   static void    stdin_readable_cb (struct ev_loop *loop, ev_io *w, int revents)    {       ev_io_stop (loop, w);      .. read from stdin here (or from w->fd) and handle any I/O errors    }     ...    struct ev_loop *loop = ev_default_init (0);    ev_io stdin_readable;    ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ);    ev_io_start (loop, &stdin_readable);    ev_run (loop, 0);

ev_timer

   static void    one_minute_cb (struct ev_loop *loop, ev_timer *w, int revents)    {      .. one minute over, w is actually stopped right here    }     ev_timer mytimer;    ev_timer_init (&mytimer, one_minute_cb, 60., 0.);    ev_timer_start (loop, &mytimer);
   static void    timeout_cb (struct ev_loop *loop, ev_timer *w, int revents)    {      .. ten seconds without any activity    }     ev_timer mytimer;    ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */    ev_timer_again (&mytimer); /* start timer */    ev_run (loop, 0);     // and in some piece of code that gets executed on any "activity":    // reset the timeout to start ticking again at 10 seconds    ev_timer_again (&mytimer);

ev_signal

   static void    sigint_cb (struct ev_loop *loop, ev_signal *w, int revents)    {      ev_break (loop, EVBREAK_ALL);    }     ev_signal signal_watcher;    ev_signal_init (&signal_watcher, sigint_cb, SIGINT);    ev_signal_start (loop, &signal_watcher);

关键代码分析


ev.h
核心h文件
typedef struct ev_watcher
{
  EV_WATCHER (ev_watcher)
} ev_watcher;
/* 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 */
libev中的基础数据类型是ev_watcher,所有的事件都可以通过(W)watcher转换成ev_watcher,ev_watcher提供通用的抽象接口ev_start、ev_stop
ev_watcher是一种c方式实现的继承、多态、封装,ev_start和ev_stop就是基类ev_watcher提供的抽象接口
ev_io/ev_timer/ev_async都继承自ev_watcher
ev.c
核心c代码
struct ev_loop
{
    ev_tstamp ev_rt_now;
    #define ev_rt_now ((loop)->ev_rt_now)
    #define VAR(name,decl) decl;
      #include "ev_vars.h"
    #undef VAR
};
reactor的核心结构体,因为成员变量众多,把详细的定义包含在ev_vars.h中。
ev_vars.h
io事件处理器列表,文件描述符fd作为数组下标
fd关注的事件发生后,查找anfds[fd]的事件处理器,检查触发事件并调用fd所有关联的处理函数。
ANFD * anfds;
ANFD的定义在ev.c中
/*保存fd事件信息的结构*/
//loop初始化的时候会初始化一个ANFD数组,每个ANFD表示一个fd对应的这个fd的所有事件信息
typedef struct
{
  //每个fd可以有多个事件
  WL head;
  unsigned char events; /* 事件的类型 */
  unsigned char reify;  /*  (EV_ANFD_REIFY, EV__IOFDSET) */
  unsigned char emask;  /* epoll后端的实际内核mask */
  unsigned char unused;
  //不同多路复用API的专用变量
  //epoll
#if EV_USE_EPOLL
  unsigned int egen;    /* generation counter to counter epoll bugs */
#endif
//windows平台
#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
  SOCKET handle;
#endif
#if EV_USE_IOCP
  OVERLAPPED or, ow;
#endif
} ANFD;
ev_io的观察列表,ev_io_start把事件处理器注册到ev_loop的fdchanges列表。
int* fdchanges;
ev_wrap.h
包装器头文件,简化了代码量,也增加了代码的阅读难度
抽几个关键的宏贴出来
#define fdchanges ((loop)->fdchanges)
#define anfds ((loop)->anfds)
这些宏是有益还是有害,仁者见仁智者见智
事件主循环
int ev_run(ev_loop *loop, int flags)
{
    //检查关注fd列表fdchanges,新增加或者修改的fd都保存在这个列表中
    //通过fd查找注册的事件处理器ANFD,检查事件处理器的关注事件
    fd_reify
    调用跨平台的多路复用api,封装过的,epoll的封装在ev_epoll.c
    backend_poll    
    把事件加入待处理列表
    ev_feed_event    
    //调用所有的待处理事件处理器
    ev_invoke_pending
}

libev笔记的更多相关文章

  1. libev事件库学习笔记

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

  2. Libev学习笔记4

    这一节首先分析Libev的定时器部分,然后分析signal部分. 对定时器的使用主要有两个函数: ev_timer_init (&timeout_watcher, timeout_cb, .) ...

  3. Libev学习笔记3

    设置完需要监听的事件之后,就开始event loop了.在Libev中,该工作由ev_run函数完成.它的大致流程如下: int ev_run (EV_P_ int flags) { do { /* ...

  4. Libev学习笔记2

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

  5. Libev学习笔记1

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

  6. libev事件库使用笔记

    源码下载地址:http://dist.schmorp.de/libev/ libev是一个高性能的事件循环库,比libevent库的性能要好. 安装: tar -zxf libev-4.15.tar. ...

  7. libev学习笔记

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

  8. blfs(systemv版本)学习笔记-编译安装i3-wm平铺式窗口管理器

    我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! i3-wm项目的官网:https://i3wm.org/ 首先需要lfs基础上编译安装完整的xorg服务 我的xorg服务编译安 ...

  9. libev 学习使用

    libev 简单的I/O库.  a high performance full featured event loop written in c libev 的大小也比 libevent 小得多并且自 ...

随机推荐

  1. 【英语】Bingo口语笔记(35) - 常见单词结尾发音

  2. ORA-00257错误

    Archiver error,connect internal only,until freed   表示归档日志目录已满,用户不能再连接数据库,现有用户可继续查询数据库,但是不能执行DML语句 插删 ...

  3. Java自增原子性问题(测试Volatile、AtomicInteger)

    这是美团一面面试官的一个问题,后来发现这是一道面试常见题,怪自己没有准备充分:i++;在多线程环境下是否存在问题?当时回答存在,接着问,那怎么解决?...好吧,我说加锁或者synchronized同步 ...

  4. python numpy argsort函数用法

    numpy.argsort numpy.argsort(a, axis=-1, kind='quicksort', order=None)[source] Returns the indices th ...

  5. C++编程常见错误

    1.成员变量要记得在构造函数中初始化 2.还是初始化!初始化!初始化!

  6. DDoS攻防战(三):ip黑白名单防火墙frdev的原理与实现

    在上一篇文章<DDoS攻防战 (二) :CC攻击工具实现与防御理论>中,笔者阐述了一个防御状态机,它可用来抵御来自应用层的DDoS攻击,但是该状态机依赖一个能应对大量条目快速增删的ip黑白 ...

  7. 自定义控件如何给特殊类型的属性添加默认值 z

    定义控件如何给特殊类型的属性添加默认值了,附自定义GroupBox一枚 标题有点那啥,但确实能表达我掌握此法后的心情. 写自定义控件时往往会有一个需求,就是给属性指定一个默认值(就是可以在VS中右键该 ...

  8. [Java]获取图片高和宽

    通过javax.imageio.ImageIO类中的read()函数读取的图片,存放在类java.awt.image.BufferedImage类中.调用BufferedImage类中的getWidt ...

  9. java 判断两个时间段是不是有交集

    如上图:X Y  Z  分别为传来的开始时间可能位于数据库中时间段的位置. X有三种可能 即传来的开始时间为与数据可中某条数据的开始位置!      这样他的结束时间就有三种可能       1.位于 ...

  10. css:outline

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...