libevent源码学习-----event操作

本文深入探讨libevent的核心结构event及event_base,详细解释了event中的各个字段及其作用,如ev_fd、ev_base、ev_events等。文章通过分析event_new、event_assign和event_add等函数,阐述了event如何注册、添加到不同队列,并强调了event_add_internal函数在超时事件管理中的关键角色。libevent利用回调函数实现事件驱动,简化了用户处理事件的逻辑。
摘要由CSDN通过智能技术生成

libevent核心结构是event_base和event,接下来主要介绍event结构

/* event的定义的主要部分 */
struct event {

    /* ... */

    /* event监听的描述符,也可以是信号值 */
    evutil_socket_t ev_fd;

    /* 事件驱动主循环 */
    struct event_base *ev_base;

    short ev_events;
    short ev_res;       /* result passed to event callback */
    short ev_flags;
    ev_uint8_t ev_pri;  /* smaller numbers are higher priority */

    union {
        /* used for io events */
        struct {
            TAILQ_ENTRY(event) ev_io_next;
            struct timeval ev_timeout;
        } ev_io;

        /* used by signal events */
        struct {
            TAILQ_ENTRY(event) ev_signal_next;
            short ev_ncalls;
            /* Allows deletes in callback */
            short *ev_pncalls;
        } ev_signal;
    } _ev;


    struct timeval ev_timeout;

    /* allows us to adopt for different types of events */
    void (*ev_callback)(evutil_socket_t, short, void *arg);
    void *ev_arg;
};

程序中使用event最开始需要event_new创建一个event

/* 创建事件驱动 */
struct event_base* base = event_base_new(); 
/*
 *创建一个事件
 *@param base: 事件驱动
 *@param fd: event对应的文件描述符,通常是通过socket创建的套接字
 *@param EV_READ: 想要监听fd的哪些事件,EV_READ表示监听fd是否可读,也可以是EV_PERSIST代表这个event是永久事件,在调用一次回调函数后仍然继续监听,对应一次性event,调用后不再监听
 *@param cb: 当fd对应的事件发生后调用的回调函数,用户提供
 *@param arg: 传给回调函数cb的参数
 */
struct event* ev = event_new(base, fd, EV_READ|EV_PERSIST, cb, arg);

接下来一个个解释每个变量的作用
evutil_socket_t ev_fd;
event负责监听的描述符,也可以是信号值

struct event_base *ev_base;
事件驱动base

short ev_events;
对应监听fd的某些事件,上述代码中是EV_READ | EV_PERSIST,可用的events包括

  • EV_READ:fd可读
  • EV_WRITE:fd可写
  • EV_PERSIST:永久事件,激活一次后仍然继续监听,对应一次事件,激活一次后不再监听
  • EV_SIGNAL:代表这个event监听的是一个信号
  • EV_TIMEOUT:代表这个event具有超时时长

short ev_res;
当event被激活时,ev_res的值记录着是被哪些事件(上述)激活,即激活的原因

short ev_flags;
event处于的状态,其实是event都在哪几个队列中(base中有多个队列),可以是以下几种的或运算

  • EVLIST_INIT:表示event刚被初始化,不在任何队列中,通常是刚调用完event_new
  • EVLIST_INSERTED:表示event处于base的注册队列中,通常是调用event_add后
  • EVLIST_ACTIVE:表示event处于base的激活队列中,通常是event被激活,等待调用回调函数
  • EVLIST_TIMEOUT:表示event处于最小堆中,表示event具有超时时间
  • EVLIST_ALL:私有空间,不明

ev_uint8_t ev_pri;
event的优先级,base的激活队列是一个数组,每个数组元素是一个队列,数组下标越低优先级越高,在统一处理激活event时,从优先级高的event开始调用回调函数

_ev

    union {
        /* used for io events */
        struct {
            TAILQ_ENTRY(event) ev_io_next;
            struct timeval ev_timeout;
        } ev_io;

        /* used by signal events */
        struct {
            TAILQ_ENTRY(event) ev_signal_next;
            short ev_ncalls;
            /* Allows deletes in callback */
            short *ev_pncalls;
        } ev_signal;
    } _ev;

主要用于记录用户提供的相对时间,ev_timeout变量

struct timeval ev_timeout;
event超时的绝对时间

void (*ev_c

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Libevent是一个事件驱动的网络编程框架,而event.h是其核心头文件之一。该头文件定义了事件处理相关的结构体、函数和宏等内容。 下面是event.h中常用的一些定义和函数: ### 1.事件回调函数 ```c typedef void (*event_callback_fn)(evutil_socket_t fd, short events, void *arg); ``` 该类型定义了事件回调函数的原型,其中fd是事件所在的文件描述符,events是事件类型,arg是用户传入的参数。 ### 2.事件结构体 ```c struct event { event_callback_fn ev_callback; // 事件回调函数 int ev_fd; // 事件所在的文件描述符 short ev_events; // 事件类型 short ev_res; // 事件结果 struct event_base *ev_base; // 事件所属的event_base void *ev_arg; // 用户传入的参数 }; ``` 该结构体表示一个事件,其中ev_callback是事件回调函数,ev_fd是事件所在的文件描述符,ev_events是事件类型,ev_res是事件结果,ev_base是事件所属的event_base,ev_arg是用户传入的参数。 ### 3.事件类型 ```c #define EV_TIMEOUT 0x01 #define EV_READ 0x02 #define EV_WRITE 0x04 #define EV_SIGNAL 0x08 #define EV_PERSIST 0x10 #define EV_ET 0x20 ``` 该宏定义了事件类型,分别为超时事件、读事件、写事件、信号事件、持续事件和边缘触发事件。 ### 4.事件处理函数 ```c struct event_base *event_base_new(void); int event_base_dispatch(struct event_base *base); int event_base_loopexit(struct event_base *base, const struct timeval *tv); void event_base_free(struct event_base *base); ``` 这些函数用于创建event_base、处理事件、退出事件循环和释放event_base等操作。 以上是event.h中的一些常用内容,更多细节可以查看源码和官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值