libevent之event_base

1.什么叫event_base(总管)
每个 event_base结构体持有一个事件集合,可以检测以确定哪些事件是激活的。
每个 event_base 都有一种用于检测哪种事件已经就绪的“方法”,或者说后端。可以识别的方法有:select,poll,epoll,kqueue,devpoll,evport,win32

2.如何创建event_base
struct event_base *event_base_new(void);大多数程序使用这个函数就可以获得一个base总管了。

2.1创建复杂的event_base
默认情况下,用event_base_new()创建的base只是使用了默认的配置。同样你也可以根据平台资源创建一个私人定制的base;你只需要一个event_config结构体,此结构体通过函数struct event_config *event_config_new(void)获得。再通过struct event_base *event_base_new_with_config(const struct event_config *cfg)函数就可以获得你特制的base了。

那么重点就落在了怎么配置event_config这个参数上了。主要完成event_config结构体四个成员变量的设置就可以了。

struct event_config {
//此队列存放着被禁止的后端
TAILQ_HEAD(event_configq, event_config_entry) entries;
//指明明CPU的数量
int n_cpus_hint;
//多路IO复用函数应该满足的特征
enum event_method_feature require_features;
//可识别的选项值
enum event_base_config_flag flags;
};

配置entries参数
对应的设置函数为 event_config_avoid_method(struct event_config *cfg, const char *method),可以通过名字让 libevent 避免使用特定的可用后端。

配置n_cpus_hint参数
对应的设置函数为event_config_set_num_cpus_hint(struct event_config *cfg, int cpus);作用是告诉event_config,系统中有多少个CPU,以便作一些对线程池作一些调整来获取更高的效率。目前,仅仅Window系统的IOCP(Windows的IOCP能够根据CPU的个数智能调整),该函数的设置才有用。

配置method_feature require_features参数
对应的设置函数为int event_config_require_features(struct event_config *cfg,
enum event_method_feature feature);让 libevent 不使用不能提供所有指定特征的后端。
enum event_method_feature {
EV_FEATURE_ET = 0x01,//要求支持边沿触发 IO的后端
EV_FEATURE_O1 = 0x02,//要求添加或删除单个事件,或者使一个事件激活的操作是 O(1)操作的后端
EV_FEATURE_FDS = 0x04,//要求支持任意文件描述符,而不仅仅是套接字的后端
};

配置flags参数
对应的设置函数为int event_config_set_flag(struct event_config *cfg,
enum event_base_config_flag flag);让 libevent 在创建 event_base 时设置一个或者多个运行时标志。
enum event_base_config_flag {
EVENT_BASE_FLAG_NOLOCK = 0x01,
EVENT_BASE_FLAG_IGNORE_ENV = 0x02,
EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,
EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,
EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};
event_config_set_flag()可识别的选项值有:
1>EVENT_BASE_FLAG_NOLOCK:不要为 event_base 分配锁。设置这个选项可以为event_base 节省一点用于锁定和解锁的时间,但是让在多个线程中访问 event_base 成为不安全的。
2>EVENT_BASE_FLAG_IGNORE_ENV:选择使用的后端时,不要检测 EVENT_*环境变量。使用这个标志需要三思:这会让用户更难调试你的程序与 libevent 的交互。
3>EVENT_BASE_FLAG_STARTUP_IOCP:仅用于 Windows,让 libevent 在启动时就启用任何必需的 IOCP 分发逻辑,而不是按需启用。
4>EVENT_BASE_FLAG_NO_CACHE_TIME:不是在每次事件循环准备执行超时回调时检测当前时间,而是在每次执行超时回调后进行检测。注意:这会消耗更多的 CPU 时间。
5>EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST :告诉 libevent ,如果决定使用epoll 后端,可以安全地使用更快的基于 changelist 的后端。epoll-changelist 后端可以在后端的分发函数调用之间,同样的 fd 多次修改其状态的情况下,避免不必要的系统调用。但是如果传递任何使用 dup()或者其变体克隆的 fd 给 libevent,epoll-changelist 后端会触发一个内核 bug,导致不正确的结果。在不使用 epoll 后端的情况下,这个标志是没有效果的。也可以通过设置 EVENT_EPOLL_USE_CHANGELIST 环境变量来 打开 epoll-changelist 选项。
6> EVENT_BASE_FLAG_PRECISE_TIMER:缺省地,Libevent尝试使用操作系统提供的更快可用的定时机制。如果存在一个更好粒度的较慢定时机制,这个标志将告诉Libevent使用它。如果系统没有提供这种更精准且慢的定时机制,此标志不起作用
上述操作 event_config 的函数都在成功时返回0,失败时返回-1。(以上摘自libevent手册)

以下的测试代码是早ubuntu下运行,libevent的版本是2.0.4-alpha

#include <stdio.h>
#include <event2/event.h>

int main(int argc, char* argv[])
{
        //配置base的参数config结构体
        struct event_config *config;
        config = event_config_new();

//      event_config_avoid_method(config,"epoll");

        //获取base结构体
        struct event_base *base;
        base = event_base_new_with_config(config);

        //获取支持的所有后端
        const char** all_methods = event_get_supported_methods();
        while( all_methods && *all_methods )
        {
                printf("%s\t", *all_methods++);
        }

        printf("\n");

        //event_base_get_method(base)获取当前支持的后端
        if( base )
                printf("current method:\t %s\n", event_base_get_method(base) );
        else
                printf("base == NULL\n");

        //释放config参数
        event_config_free(config);

        return 0;
}

编译运行就可以得到如下结果
epoll poll select
current method: epoll
将以上注释掉的c代码取消注释,编译运行可以得到如下的结果
epoll poll select
current method: poll
前后对比可以知道,第二次避免使用epoll之后,会自动退其次使用poll
这就是对base进行了定制,其他的三个参数就不都介绍了。

const char **event_get_supported_methods(void);
const char event_base_get_method(const struct event_base );
int event_base_get_features(const struct event_base *base);
static int event_config_is_avoided_method(const struct event_config *cfg,
const char *method);
第一个函数是获取当前系统所支持的多路IO复用函数有哪些。第二个函数需要一个event_base结构体作为参数,说明是在new到一个event_base之后才能调用的。该函数返回值是对应event_base* 当前所采用的多路IO复用函数是哪个。第三个函数则是获取参数event_base当前所采用的特征是什么。第四个函数则说明参数method指明的多路IO复用函数是不是被参数config所禁用了。如果是禁用了,返回非0值。不禁用就返回0。

有点粗糙!仅此记录一下而已。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值