libevent(5)libevent中的上下文属性配置

1、创建上下文

libevent 创建上下文方法,默认 event_base_new():

struct event_base *event_base_new(void);

也可以根据配置创建上下文:

struct event_base *event_base_new_with_config(const struct event_config *);

在使用 event_config_new 创建完 event_base 上下文后,必须使用 event_config_free 进行释放,否则会有内存泄漏。

2、获取和设置网络模式

// 1.显示支持的网络模式
const char **event_get_supported_methods(void);

// 2.获取当前的网络模型
const char *event_base_get_method(const struct event_base *);

// 3.设置网络模型,使用select。Windows上无效
int event_config_avoid_method(struct event_config *cfg, const char *method);

libevent 中支持的网络模型选项位于 event.c 中:

/* Array of backends in order of preference. */
static const struct eventop *eventops[] = {
#ifdef EVENT__HAVE_EVENT_PORTS
	&evportops,
#endif
#ifdef EVENT__HAVE_WORKING_KQUEUE
	&kqops,
#endif
#ifdef EVENT__HAVE_EPOLL
	&epollops,
#endif
#ifdef EVENT__HAVE_DEVPOLL
	&devpollops,
#endif
#ifdef EVENT__HAVE_POLL
	&pollops,
#endif
#ifdef EVENT__HAVE_SELECT
	&selectops,
#endif
#ifdef _WIN32
	&win32ops,
#endif
	NULL
};

3、设置特征参数

int event_config_require_features(struct event_config *cfg, int feature);

feature 指定特征方法,可用参数:

(1)EV_FEATURE_ET 使用边沿触发,支队 epoll 有效;
(2)EV_FEATURE_O1 要求添加、删除单个事件,或者确定哪个事件激活的操作是 O(1) 的复杂度;
(3)EV_FEATURE_FDS 要求支持任意文件描述符,而不仅仅是套接字;
(4)EV_FEATURE_EARLY_CLOSE 检测连接关闭事件。允许使用 EV_CLOSED 检测连接关闭,但不确定在所有内核版本上都支持,需要进行检测判断。

4、设置标志位

int event_config_set_flag(struct event_config *cfg, int flag);

flag 可用参数:

(1)EVENT_BASE_FLAG_NOLOCK 不要为 event_base 分配锁。设置这个选项可以为 event_base 节省一点用于锁定和解锁的时间,但会让多个线程不安全;
(2)EVENT_BASE_FLAG_IGNORE_ENV 作为后端程序时,不要检测 EVENT_* 环境变量。使用这个标志需要三思:可能受环境变量影响程序调试;
(3)EVENT_BASE_FLAG_STARTUP_IOCP 仅用于 Windows,启用任何必须的 IOCP 分发逻辑必须要初始化 IOCP 多线程,即调用 evthread_use_windows_threads 和 event_config_set_num_cpus_hint 函数;
(4)EVENT_BASE_FLAG_NO_CACHE_TIME 不在事件循环执行超时回调时检测当前时间,而是在每次超时回调后检测,设置后时间会更精确。但目前我还并不明白具体用途,一般情况下也用不到;
(5)EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST epoll下有效,防止同一个 fd 多次激发事件,fd 如果做复制会有 bug;
(6)EVENT_BASE_FLAG_PRECISE_TIMER 默认使用系统最快的计时机制,如果系统有较慢但更精确的计时,则采用。但更精确的计时机制一般会伴随更复杂的调用,可能会有效率问题。
这些参数在 Linux 编程中并不常用,但在 Windows 编程中,EVENT_BASE_FLAG_STARTUP_IOCP 标志经常会用到,因为 Windows 只支持 IOCP 模式。

5、一个完整的例子

//libevent上下文属性配置
// 
//event_base_new_with_config:
//      event_config_new(void) - event_config_set_flat
//                             - event_config_avoid_method()
//                             - event_config_require_features() - event_method_feature
// 
//      event_config_free(struct event_config *cfg)
//      event_config_avoid_method(struct event_config* cfg, const char* method)
// 
//      event_method_feature:
//      event_config_set_num_cpus_hint
// 
//event_config_set_flag
//event_config_required_feature

//event_config_avoid_method

#include <iostream>
#include <signal.h>
#include <event2/event.h>

int main()
{
#ifdef _WIN32
    //windows初始化socket库
    WSADATA wsa;
    WSAStartup(MAKEWORD(2, 2), &wsa);
#else
    //发送数据给已关闭socket时,忽略管道信息.
    //否则可能导致程序dump.
    if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
        return -1;
    }
#endif

    //创建配置上下文
    event_config* conf = event_config_new();

    //显示支持的网络模式
    const char** methods = event_get_supported_methods();
    std::cout << "supported methods:" << std::endl;
    for (int i = 0; methods[i] != NULL; i++) {
        //1. windows下: 只显示 win32
        //2. linux下: 显示 
        std::cout<< methods[i] << std::endl;
    }

    //设置特征
    //在windows中EV_FEATURE_FDS无效
    //设置了EV_FEATURE_FDS后,其他特征就无法设置
    event_config_require_features(conf, EV_FEATURE_ET | EV_FEATURE_O1);

    //初始化libevent配置上下文
    event_base* base = event_base_new_with_config(conf);
    event_config_free(conf);

    if (!base) {
        std::cerr << "event_base_new_with_config failed!" << std::endl;

    } else {
        std::cout << "event_base_new_with_config success!" << std::endl;
        //获取特征
        int f = event_base_get_features(base);
        if (f & EV_FEATURE_ET) {
            std::cout << "EV_FEATURE_ET supported." << std::endl;
        }
        else {
            std::cout << "EV_FEATURE_ET not supported." << std::endl;
        }

        if (f & EV_FEATURE_O1) {
            std::cout << "EV_FEATURE_O1 supported." << std::endl;
        }
        else {
            std::cout << "EV_FEATURE_O1 not supported." << std::endl;
        }

        if (f & EV_FEATURE_FDS) {
            std::cout << "EV_FEATURE_FDS supported." << std::endl;
        }
        else {
            std::cout << "EV_FEATURE_FDS not supported." << std::endl;
        }

        if (f & EV_FEATURE_EARLY_CLOSE) {
            std::cout << "EV_FEATURE_EARLY_CLOSE supported." << std::endl;
        }
        else {
            std::cout << "EV_FEATURE_EARLY_CLOSE not supported." << std::endl;
        }

        event_base_free(base);
    }

#ifdef _WIN32
    //清理window的socket库
    WSACleanup();
#endif

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值