【Libevent】Libevent特征和事件集创建

2023-11-16

1.libevent特点

  • 事件驱动,高性能
  • 轻量级,专注于网络;
  • 跨平台,支持Windows、Linux、Linux、Mac Os等
  • 支持多种I/O多路复用技术,epoll、poll、dev/poll、select、kqueue等
  • 支持I/O,定时器和信号等事件

2.event_base

使用 libevent 函数之前需要分配一个或者多个 event_base 结构体。每个 event_base 结构 体持有一个事件集合,可以检测以确定哪个事件是激活的。

如果设置 event_base 使用锁,则可以安全地在多个线程中访问它 。然而,其事件循环只能 运行在一个线程中。如果需要用多个线程检测 IO,则需要为每个线程使用一个 event_base。

每个 event_base 都有一种用于检测哪种事件已经就绪的 “方法”,或者说后端。可以识别的方法有:

select、poll、epoll、kqueue、devpoll、evport、win32

2.1创建默认的event_base

***event_base_new()***函数分配并且返回一个新的具有默认设置的 event_base。函数会检测环境变量,返回一个到 event_base 的指针。如果发生错误,则返回 NULL。

struct event_base *event_base_new(void);
2.2创建复杂的event_base

要对event_base有更多的控制,需要使用event_config函数。event_config 是一个容纳 event_base 配置信息的不透明结构体。需要 event_base 时,将 event_config 传递给event_base_new_with_config ()

创建接口

分配一个event_config结构体
struct event_config *event_config_new(void);

获取新的event_base
struct event_base* event_base_new_with_config(const struct event_config *cfg);

释放event_config
void event_config_free(struct event_config *cfg);

使用步骤

  • 要使用这些函数分配event_base,先调用 event_config_new()分配一个 event_config。
  • 然后,对 event_config 调用其它函数,设置所需要的 event_base 特征。
  • 最后,调用 event_base_new_with_config()获取新的 event_base。
  • 完成工作后,使用 event_config_free ()释放 event_config。
2.3设置event_ base特征

vent_config_avoid_method()

调用 event_config_avoid_method ()可以通过名字让 libevent 避免使用特定的可用后端 。

int event_config_avoid_method(struct event_config *cfg, const char *method);

event_config_require_features()

调用 event_config_require_feature ()让 libevent 不使用不能提供所有指定特征的后端,底层也是一个位图

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

event_config_require_features()可识别的特征值有:

  • EV_FEATURE_ET:要求支持边沿触发的后端
  • EV_FEATURE_O1:要求添加、删除单个事件,或者确定哪个事件激活的操作是 O(1)复杂度的后端
  • EV_FEATURE_FDS:要求支持任意文件描述符,而不仅仅是套接字的后端

event_config_set_flag()

让libevent 在创建 event_base 时设置一个或者多个将在下面介绍的运行时标志。

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


常用的特征属性,底层是一个位图
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()可识别的选项值有:

  • EVENT_BASE_FLAG_NOLOCK :不要为 event_base 分配锁。设置这个选项可以为 event_base节省一点用于锁定和解锁的时间,但是让在多个线程中访问event_base成为不安全的。
  • EVENT_BASE_FLAG_IGNORE_ENV :选择使用的后端时,不要检测 EVENT_* 环境 变量。使用这个标志需要三思:这会让用户更难调试你的程序与 libevent 的交互。
  • EVENT_BASE_FLAG_STARTUP_IOCP:仅用于 Windows,让 libevent 在启动时就 启用任何必需的 IOCP 分发逻辑,而不是按需启用。
  • EVENT_BASE_FLAG_NO_CACHE_TIME :不是在事件循环每次准备执行超时回调时 检测当前时间,而是在每次超时回调后进行检测。注意:这会消耗更多的 CPU时间。
  • 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 选项。
2.4检测event_base后端
2.4.1接口一

有时候要检查 event_base 支持哪些特征,或者当前使用哪种方法。

const char **event_get_supported_methods(void);

event_get_supported_methods()函数返回一个指针 ,指向 libevent 支持的方法名字数组。这个数组的最后一个元素是 NULL。

实例

int i;
const char **methods = event_get_supported_methods();
for (i=0; methods[i] != NULL; ++i) {
    printf("    %s\n", methods[i]);
}
2.4.2接口二
const char *event_base_get_method(const struct event_base *base);

enum event_method_feature event_base_get_features(const struct event_base *base);
  • event_base_get_method()返回event_base正在使用的方法。
  • event_base_get_features()返回event_base支持的特征的比特掩码。

实例

struct event_base *base;
enum event_method_feature f;

base = event_base_new();
if (!base) 
{
    puts("Couldn't get an event_base!");
} 
else {
    printf("Using Libevent with backend method %s.",event_base_get_method(base));
    f = event_base_get_features(base);
    if ((f & EV_FEATURE_ET))
        printf("  Edge-triggered events are supported.");
    if ((f & EV_FEATURE_O1))
        printf("  O(1) event notification is supported.");
    if ((f & EV_FEATURE_FDS))
        printf("  All FD types are supported.");
    puts("");
}
2.5释放event_base

使用完 event_base 之后,使用 event_base_free()进行释放。

void event_base_free(struct event_base *base);
2.6event_base优先级

libevent支持为事件设置多个优先级。然而, event_base默认只支持单个优先级。可以调用 event_base_priority_init()设置 event_base 的优先级数目。

int event_base_priority_init(struct event_base *base, int n_priorities);

成功时这个函数返回 0,失败时返回 -1。base 是要修改的 event_base,n_priorities 是要支持的优先级数目,这个数目至少是 1 。每个新的事件可用的优先级将从 0 (最高) 到 n_priorities-1(最低)。

2.7event_base和fork

不是所有事件后端都在调用fork()之后可以正确工作。比如在fork()前的地方创建,会发生写时拷贝。

所以,如果在使用fork()或者其他相关系统调用启动新进程之后,希望在新进程中继续使用 event_base,就需要进行重新初始化。

int event_reinit(struct event_base *base);

成功时这个函数返回 0,失败时返回 -1。

实例

struct event_base *base = event_base_new();
/* ... add some events to the event_base ... */
if (fork()) {
    /* In parent */
    continue_running_parent(base); /*...*/
} else {
    /* In child */
    event_reinit(base);		//在子进程中注册event_base事件
    continue_running_child(base); /*...*/
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Libevent】Libevent特征和事件集创建 的相关文章

  • 双机热备 ip地址_SBC双机热备方案

    概述 随着通信全IP化的进程 现代企业中基于IP的语音 视频 会议 融合通信已广泛应用 同时企业通信也面临着新挑战 包括安全攻击 跨网NAT穿越以及业务稳定运行 高可靠方案尤为重要 因此在组网中部署SBC Session Border Co
  • NPN和PNP三极管原理以及应用电路设计

    一 基本概念与原理 三极管最主要的功能是电流放大 模拟电路 和开关作用 数字电路 常用的三极管有 S9014 S8550等型号 三极管由两个PN结构成 共用的一个电极成为三极管的基极 用字母b表示 其他的两个电极成为集电极 用字母c表示 和
  • 安卓加固基础(二)

    4 反调试 4 1 思路一 一个进程最多只能被一个进程ptrace 本文章主要针对安卓so反调试和最初的加壳方法进行了一下总结 在处于调试状态时 Linux会向 proc pid status写入一些进程状态信息 比如TracerPid字段
  • 【leetcode 力扣刷题】删除字符串中的子串or字符以满足要求

    删除字符串中的子串或者字符以满足题意要求 1234 替换子串得到平衡字符串 680 验证回文串 917 仅仅反转字母 1234 替换子串得到平衡字符串 题目链接 1234 替换子串得到平衡字符串 题目内容 题目中给出了平衡字符串的定义 只有
  • TypeScript 初识笔记

    目录 一 基础静态类型和对象类型 二 类型注解和类型推断 三 元组的使用和类型约束 四 接口 五 类 六 联合类型和类型保护 七 枚举 八 泛型 九 tsconfig json文件 TypeScript 其实就是 JavaScript 的超
  • 教程:在Vivado中指定VSCode作为文本编辑器

    教程 在Vivado中指定VSCode作为文本编辑器 更新历史 20190325 首次发布 20201027 对本文第三步中需要填写的内容做了修改 使得VSCode能够实现光标的自动定位 该修改的做法是 HK Journalist 在评论中
  • Vue组件间通信方式都有哪些?

    一 组件间通信的概念 组件间通信这个词进行拆分 组件 通信 都知道组件是vue最强大的功能之一 vue中每一个 vue可以视之为一个组件通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的 广义上 任何信息的交通都是通信组
  • 一个方案提升Flutter内存利用率(干货)

    背景 我们闲鱼使用的图片方案是自研的外接纹理方案 Android侧创建SurfaceTexture 通过FlutterJNI注册到Flutter engine里 最后返回texture id给Flutter应用层 应用层使用Texture

随机推荐