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. HDU 3078 Network

    简单的  RMQ:  先预处理得到  所有 节点的 公共祖先  和  dfs 得到所有节点的父亲节点:  然后  询问时,从自己出发向上找父亲, 然后  得到所有的节点:排序一下 不知道  这题这样也 ...

  2. 定时组件quartz系列<二>quartz的原理

    Quartz是一个大名鼎鼎的Java版开源定时调度器,功能强悍,使用方便.   一.核心概念   Quartz的原理不是很复杂,只要搞明白几个概念,然后知道如何去启动和关闭一个调度程序即可.   1. ...

  3. Android WebView中那些不得不解决的坑~~

    前面那张hybrid开发心得 有人问 怎么解决不用onJsPrompt 来回调js函数的问题.其实很简单,就是在在你的jscalljava回调函数内 另外开个线程去load js代码即可: wb.po ...

  4. 设计模式-单键(Singleton)

    [摘要]   在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性.以及良好的效率. 如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例? 这应该 ...

  5. 怎样预防Ddos攻击

    一.为何要DDOS? 随着Internet互联网络带宽的增加和多种DDOS黑客工具的不断发布,DDOS拒绝服务攻击的实施越来越容易,DDOS攻击事件正在成上升趋势.出于商业竞争.打击报复和网络敲诈等多 ...

  6. unittest框架的注意点

    这篇并不是讲unittest如何使用,而是记录下在和htmltestrunner集成使用过程中遇到的一些坑,主要是报告展示部分. 我们都知道python有一个单元测试框架pyunit,也叫unitte ...

  7. duilib让不同的容器使用不同的滚动条样式

    装载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/42240569 以前在给一个容器设置横纵向的滚动条时,一直是通过设置xml ...

  8. 【leetcode】155 - Min Stack

    Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. pu ...

  9. pick定理:面积=内部整数点数+边上整数点数/2-1

    //pick定理:面积=内部整数点数+边上整数点数/2-1 // POJ 2954 #include <iostream> #include <cstdio> #include ...

  10. 使用JavaMail API发送邮件

    发送邮件是很常用的功能,注册验证,找回密码,到货通知,欠费提醒等,都可以通过邮件来提醒. Java中发送邮件需要使用javax.mail.jar包,读者可以上网搜索或去官方下载,下载地址为: 下面贴上 ...