在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(); //使用默认的。
}