• libev笔记


    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

    }
  • 相关阅读:
    docker简单入门之使用docker容器部署简单的java web开源项目jpress博客程序
    go语言的安装、环境变量配置及简单使用
    bootstrap4简单使用和入门02-bootstrap的js组件简单使用
    bootstrap4简单使用和入门01-简单表单的使用
    bootstrap4简单使用和入门03-响应式布局
    python操作三大主流数据库(14)python操作redis之新闻项目实战②新闻数据的展示及修改、删除操作
    python操作三大主流数据库(13)python操作redis之新闻项目实战①新闻数据的导入
    python操作三大主流数据库(12)python操作redis的api框架redis-py简单使用
    python操作三大主流数据库(11)redis的安装和简单使用
    python操作三大主流数据库(10)python操作mongodb数据库④mongodb新闻项目实战
  • 原文地址:https://www.cnblogs.com/learn-my-life/p/5636362.html
Copyright © 2020-2023  润新知