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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值