Libevent

libevent的配置event_base

Posted by Liangjf on April 14, 2019

在libevent中,最重要之一的结构体非 event_base 莫属了。

在libevent中,可以通过 event_init 或者 event_base 得到。前者得到的是默认配置的base,后者得到的是自定义配置的base。

base是什么?就是event_base,整个libevent中Reactor架构的事件集。

看看自定义的base吧。

struct event_base *
event_base_new(void)
{
    struct event_base *base = NULL;
    struct event_config *cfg = event_config_new();
    if (cfg) {
        base = event_base_new_with_config(cfg);
        event_config_free(cfg);
    }
    return base;
}

就是通过 event_config_new 函数得到一个配置,然后通过传参传进去 event_base_new_with_config 配置base。同时,也可以看到 event_init 其实就是直接把NULL传进去 event_base_new_with_config 里面就会判空,不会使用自定义配置了。

因此可以得到,event_config 结构就是配置 base 的数据结构了。

struct event_config {
	TAILQ_HEAD(event_configq, event_config_entry) entries;//拒绝使用某个io多路复用模型

	int n_cpus_hint;		//智能调整CPU个数
	struct timeval max_dispatch_interval;   //调度的间隔
	int max_dispatch_callbacks;
	int limit_callbacks_after_prio;
	enum event_method_feature require_features;
	enum event_base_config_flag flags;
};

enum event_method_feature require_features有以下的类型:

enum event_method_feature {
    EV_FEATURE_ET = 0x01,   //支持边沿触发
    EV_FEATURE_O1 = 0x02,//添加、删除、或者确定哪个事件激活这些动作的时间复杂度都为O(1)。select、poll是不能满足这个特征的.epoll则满足
    EV_FEATURE_FDS = 0x04,  //支持任意的文件描述符,而不能仅仅支持套接字
    EV_FEATURE_EARLY_CLOSE = 0x08   //延迟关闭
};

enum event_base_config_flag flags有以下的类型:

enum event_base_config_flag {
    EVENT_BASE_FLAG_NOLOCK = 0x01,  //不为event_base分配锁
    EVENT_BASE_FLAG_IGNORE_ENV = 0x02,//选择多路IO复用函数时,不检测EVENT_*环境变量
    EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,    //仅用于Windows的IOCP
    EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,//执行event_base_loop时没cache时间
    EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,//用libevent的changelist_epoll
    EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};

由对应的接口设置对应的属性:

  • event_config_set_flag
  • event_config_avoid_method
  • event_config_require_features
  • event_config_set_num_cpus_hint
  • event_config_set_max_dispatch_interval

为了使程序更加健壮,以防有些平台不支持设置base,我们最好在程序这样处理:

event_config *cfg = event_config_new();
event_config_require_features(cfg,  EV_FEATURE_O1 | EV_FEATURE_FDS);
event_base *base = event_base_new_with_config(cfg);
if( base == NULL )
{
	 base = event_base_new(); //使用默认的。
}