• libevent 使用流程


    libevent 使用流程

    使用流程

    1. 创建一个事件处理框架
    2. 创建一个事件
    3. 事件添加到处理框架
    4. 开始事件循环
    5. 释放资源

    事件处理框架 - event_base

    1. 使用libevent函数之前需要分配一个或者多个event_base结构体. 每个event_base结构体有一个事件集合,可以检测以确定哪个事件是激活的.

      • 相当于epoll红黑树的树根
      • 底座
      • 抽象层,完成对event_base的封装
      • 每个event_base都有一种用于检测那种事件已经就绪的"方法",或者说后端
    2. 具体操作

      • 创建event_base
        • struct event_base* event_base_new(void);
        • 失败返回NULL
      • 释放event_base
        • event_base_free(struct event_base* base);
      • 循环监听base对应的事件, 等待条件满足
        • event_base_dispatch(struct event_base* base);
    3. 查看event_base封装的后端(当前系统中支持那些函数)

      • const char **event_get_supported_methods();
      • 返回一个字符串数组中
      • const char * event_base_get_method(const struct event_base *base);
      • 返回当前使用的IO转接
    4. event_base和fork

      • 子进程创建成功后,父进程可以继续使用event_base
      • 子进程中需要继续使用event_base需要重新进行初始化
        • int event_reinit(struct event_base * base)

    事件 - event

    1. 创建新事件
    
    #define  EV_TIMEOUT         0x01    // 废弃
    #define  EV_READ            0x02
    #define  EV_WRITE           0x04
    #define  EV_SIGNAL          0x08
    #define  EV_PERSIST         0x10    // 持续触发
    #define  EV_ET              0x20    // 边沿模式
    
    typedef void(*event_callback_fn)(evutil_sockt_t,short,void *);
    
    struct event *event_new(
        struct event_base *base,
        evutil_socket_t fd,     // 文件描述符-int
        shord what,
        event_callback_fn cb,   // 事件处理动作
        void *arg
    );
    
    1. 释放事件

      • void event_free(struct event *event);
    2. 设置未决事件(有资格但是没有被处理的事件)

      • 构造事件之后,在将其添加到 event_base 之前实际上是不能对其做任何操作的。使用event_add()将事件添加到event_base, 非未决事件 -> 未决事件.
      • 函数
        int event_add(
            struct event *ev, 
            const struct timeval *tv
        ); 
        
      • tv:
        • NULL: 事件被触发, 对应的回调被调用
        • tv = {0, 100}, 如果设置的时间,
          • 在改时间段内检测的事件没被触发, 时间到达之后, 回调函数还是会被调用
      • 函数调用成功返回0, 失败返回-1
    3. 设置非未决(还没有资格被处理的事件)

      • int event_del(struct event *ev);
      • 对已经初始化的事件调用 event_del()将使其成为非未决和非激活的。如果事件不是未决的或者激活的,调用将没有效果。成功时函数返回 0,失败时返回-1。

    事件循环

    1. 开始循环

      • 一旦有了一个已经注册了某些事件的 event_base, 就需要让 libevent 等待事件并且通知事件的发生。
      #define EVLOOP_ONCE                        0x01
      	事件只会被触发一次
      	事件没有被触发, 阻塞等
      #define EVLOOP_NONBLOCK                    0x02
      	非阻塞 等方式去做事件检测
      	不关心事件是否被触发了
      #define EVLOOP_NO_EXIT_ON_EMPTY  0x04
      	没有事件的时候, 也不退出轮询检测
      
      • int event_base_loop(struct event_base *base, int flags);
        • 正常退出返回0, 失败返回-1
      • event_base_dispatch(struct event_base* base)
        • 等同于没有设置标志的 event_base_loop()
        • 将一直运行,直到没有已经注册的事件了,或者调用 了event_base_loopbreak()或者 event_base_loopexit()为止。
    2. 停止循环

      • 返回值:成功0,失败-1
      struct timeval{
          long tv_sec;
          long tv_usec;
      };
      
      • 如果 event_base 当前正在执行激活事件的回调 ,它将在执行完当前正在处理的事件后立即退出
      int event_base_loopexit(
          struct event_base *base,
          const struct timeval *tv
      );
      
      • 让event_base 立即退出循环
      int event_base_loopbreak(struct event_base *base);
      
  • 相关阅读:
    使用SharePoint文档库需注意的问题
    Windows 2003 lassess.exe 系统错误
    使用javascript 实现.net 验证控件功能
    NetAdvantage For .NET全新推出 2008 Volume 2 版加强了对web图表的支持
    Aspose.Total 发布Q12010第一季度版
    FastReport VCL4.9发布
    StimulReport.Net报表控件推介
    .NET Reactor超高性价比的混淆器
    TeeChartfor.NET 全面支持VisualStudio2010和.NET Framework4.0 (控件中国网)
    Dundas Dashboard V2.0仪表盘控件的发布
  • 原文地址:https://www.cnblogs.com/joker-wz/p/10735410.html
Copyright © 2020-2023  润新知