libevent源码学习(6):事件处理基础——event_base的创建

目录

前言

创建默认的event_base

event_base的配置

event_config结构体

创建自定义event_base——event_base_new_with_config

禁用(避免使用)某一种IO复用模型

设置IO复用模型需要满足的特征

设置event_base的flag特性

获取event_base所满足的特征

获取当前系统所支持的IO复用模型

总结


以下源码均基于libevent-2.0.21-stable。

前言

       要实现libevent的事件处理,最关键的就是event_base,event_base就像是一棵树,而需要进行处理的事件event就像是树上的果子,因此,在分析libevent的事件处理之前,先来分析一下event_base。

       由于event_base结构体中包含了三十多个成员,直接去分析每个成员是比较麻烦并且没有太大意义的,因此个人觉得从event_base的使用中去了解event_base各个结构体成员的作用会比较好,因此这里先来看看event_base的创建。

创建默认的event_base

       在event.c中,可以看到event_base有两种创建方式。

       目前最常用的一种方式是使用event_base_new,该函数的定义如下:

struct event_base *
event_base_new(void)
{
	struct event_base *base = NULL;
	struct event_config *cfg = event_config_new();  
	if (cfg) {  //cfg非空,说明event_config分配成功
		base = event_base_new_with_config(cfg);  //将cfg配置到base中去
		event_config_free(cfg);  //清空cfg链表
	}
	return base;
}//event.c

        可以发现,该函数是创建了一个event_base并最终返回了它,并且该函数无需传入任何参数,也就是说,如果调用该函数来创建一个event_base,那么返回得到的就是一个默认的base,而event_base_new也就是默认的event_base创建函数。关于其中使用到的event_config相关的函数,下面会分析。

       除了这种创建方式外,还有另一种创建方式event_init,该函数声明如下:

/**
  Initialize the event API.

  The event API needs to be initialized with event_init() before it can be
  used.  Sets the global current base that gets used for events that have no
  base associated with them.

  @deprecated This function is deprecated because it replaces the "current"
    event_base, and is totally unsafe for multithreaded use.  The replacement
    is event_base_new().

  @see event_base_set(), event_base_new()
 */
struct event_base *event_init(void);//event.h

       首先关注到该函数定义的描述文字中有一个@deprecated,这说明该函数是不推荐使用并且有替代品的。并提到该函数不是线程安全的,替代函数就是event_base_new。来看看该函数定义:

struct event_base *
event_init(void)
{
	struct event_base *base = event_base_new_with_config(NULL); //默认方式创建一个base 相当于调用了一个event_base_new

	if (base == NULL) {
		event_errx(1, "%s: Unable to construct event_base", __func__);
		return NULL;
	}

	current_base = base;

	return (base);
}

       在event_init函数中,创建一个新的event_base是用NULL为参数调用event_base_new_with_config的,这实际上就相当于调用了默认的event_base_new。并且在最后用current_base来保存新创建的event_base,这里的current_base是一个全局变量,这也是导致该函数线程不安全的原因。查看了一下其他资料,提到event_init实际上是老版本libevent中使用到的创建函数,不过现在相当于被废弃了,只不过为了兼容低版本,还依然保存着。

       这里分析了创建一个默认的event_base,那么如果创建一个自定义的event_base呢?并且自定义的event_base中有哪些属性是可以自定义的呢?

event_base的配置

       创建一个自定义的event_base是通过函数event_base_new_with_config来实现的,该函数声明如下:

struct event_base *event_base_new_with_config(const struct event_config *);

       该函数需要传入一个event_config参数,而该参数则包含了用户自定义的配置信息&#

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
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中的一些常用内容,更多细节可以查看源码和官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值