libevent的event管理相关接口

目录

  • 4. 事件管理
    • 4.1 event_new
      • 功能
      • 备注
      • 原型
    • 4.2 event_free
      • 功能
      • 备注
      • 原型
    • 4.3 event_debug_unassign
      • 功能
    • 备注
    • 4.4 event_add
      • 功能:
      • 备注:
      • 原型:
    • 4.5 event_del
      • 功能
      • 备注
      • 原型
    • 4.6 event_base_once
      • 功能
      • 备注
      • 原型:
    • 4.7 event_pending
      • 功能
      • 备注
      • 原型
    • 4.8 event_self_cbarg
      • 功能
      • 备注
      • 原型
    • 4.9 event_assign
      • 功能
      • 备注
      • 原型
    • 4.10 event_finalize
      • 功能
      • 备注
      • 原型
    • 4.11 event_free_finalize
      • 功能
      • 备注
      • 原型
    • 4.12 event_remove_timer
      • 功能
    • 原型
    • 4.13 event_del_noblock
      • 功能
      • 备注
      • 原型
    • 4.14 event_del_block
      • 功能
      • 备注
      • 原型
    • 4.15 event_active
      • 功能
      • 备注
      • 原型
    • 4.16 event_initialized
      • 功能
      • 备注
      • 原型
    • 4.17 event_get_fd
      • 功能
      • 备注
      • 原型
    • 4.18 event_get_base
      • 功能
      • 备注
      • 原型
    • 4.19 event_get_events
      • 功能
      • 备注
      • 原型
    • 4.20 event_get_callback
      • 功能
      • 备注
      • 原型
    • 4.21 event_get_callback_arg
      • 功能
      • 备注
      • 原型
    • 4.22 event_get_priority
      • 功能
      • 备注
      • 原型
    • 4.23 event_get_assignment
      • 功能
      • 备注
      • 原型
    • 4.24 event_get_struct_event_size
      • 功能
      • 备注
      • 原型
    • 4.25 event_base_priority_init
      • 功能
      • 备注
      • 原型
    • 4.26 event_base_get_npriorities
      • 功能
      • 备注
      • 原型
    • 4.27 event_priority_set
      • 功能
      • 备注
      • 原型
    • 4.28 event_set_mem_functions
      • 功能
      • 备注
      • 原型
    • 4.29 event_base_set
      • 功能
      • 备注
      • 原型
    • 4.30 event_gettime_monotonic
      • 功能
      • 备注
      • 原型

4. 事件管理

4.1 event_new

功能

分配并初始化一个event事件,后续可以将这个event添加到event_base。

备注

多个event同时对同一个文件句柄进行监听是OK的。但是它们必须要么同时是边缘触发的类型,要么同时是水平触发类型。

原型

struct event *event_new(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg);

输入参数:

  • fd: 对于socket事件,则对应socket句柄,对于文件事件,则对应文件句柄。
    对于signal事件,则对应signal号
    对于timer事件,则设置为-1
  • events:当前event事件所关联的事件类型,多个事件类型可以通过二进制位OR来传递
         包括EV_READ, EV_WRITE, EV_SIGNAL, EV_PERSIST, EV_ET。其中EV_PERSIST表示event一旦被event_add以后就一直处于事件的监视状态,除非通过event_del删除。其中EV_SIGNAL表示该event事件监听的是signal信号,而不是io事件。
  • callback: 事件回调函数
  • callback_arg: 事件回调的上下文参数

以下是event_callback_fn的类型定义:


typedef void (*event_callback_fn)(evutil_socket_t fd, short events, void *callback_arg);

4.2 event_free

功能

回收一个由event_new分配的event。

备注

原型

void event_free(struct event *);

4.3 event_debug_unassign

功能

启用一些相对代价比较高的正常情况下都是关闭的调试检查手段。

备注

通常,这些检查使源码能在在crash之前,通过assert来捕获错误信息。注意,本函数必须在任何
event_base 或者 event被创建之前被调用。开启了调试模式后,可以捕获以下错误:

  • 添加事件的时候发现一个event被重复assign。
  • 在未分配(non-assign)事件上调用任何函数。

4.4 event_add

功能:

添加一个事件到event_base事件循环中,使其进入pending状态。

备注:

event_add将event事件放入事件调度中,当通过event_assgin或者event_new设置的事件的条件满足的时候,或者当指定的超时时间到了以后,调度器将会调用对应的回调函数。
在调用本函数前,event本身必须是已经通过 event_assign或者 event_new初始化过的。
而且,只有在event不再处于pending状态下,才可以重新调用event_assign进行初始化。
如果当前event已经在之前通过event_add设置了超时,那么本次调用将会为该event设置新的超时时间(如果timeout参数不为NULL)

原型:

int event_add(struct event *ev, const struct timeval *timeout);

4.5 event_del

功能

从调度器中删除一个指定的事件。

备注

调用本函数,不光将指定的event不再处于pending状态,另外,如果有设置超时定时器,也将一并取消。

原型

int event_del(struct event *ev);

4.6 event_base_once

功能

对于一个文件句柄进行一次调度。

备注

本函数不需要我们提前预先准备一个event,而只要通过指定文件句柄,所关心的事件类型,和回调函数、超时时间等参数就可以监听该句柄上的事件,对于一次性事件,只需要一行代码,就会比较方便。

注意:在libevent 2.0以及之前的版本,如果event永远没有被触发,那么用来保持它的内部内存将永远不会被释放。在libevent 2.1,内部内存将会在event_base_free的调用中被释放掉。但是,函数中的arg参数是不会被释放的,这个是需要你自己来决定什么时候进行释放的。

原型:

int event_base_once(struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *arg, const struct timeval *timeout);

4.7 event_pending

功能

判断一个event事件是否已经被添加到event_base中并处于pending状态了。

备注

原型

int event_pending(const struct event *ev, short events, struct timeval *tv);

输入参数:

  • ev:
  • events: 所要查询的事件类型
  • tv: 如果tv != NULL,那么对于timeout类型的event,tv指向的timeval将返回超时的时间。

4.8 event_self_cbarg

功能

返回一个用来告诉libevent将来在回调事件回调函数的时候必须用event的指针作为其上下文参数。

备注

由于在event_new的时候,需要我们提供事件的回调函数以及回调函数的上下文参数,如果开发者需要把event本身作为回调函数的上下文参数时,event事件本身还没有被创建,所以这个时候可以通过调用event_self_cbarg生成一个占位值告诉libevent。

原型

void *event_self_cbarg(void);

4.9 event_assign

功能

准备一个新的已经分配好内存的event事件,将其与socket句柄或者signal进行绑定,并且绑定该event事件所关心的事件类型等。

备注

区别于event_new,event_assign分配一个新的event事件,而是对已经分配好的event事件进行绑定和初始化操作。
开发人员通过自己为event分配内存然后event_assign绑定并初始化event的操作,增加了编程的灵活性,但是带来了一个副作用,因为分配内存的时候我们一般通过sizeof(event)来得到event结构体所占用的内存空间大小的,但是这样会因为未来libevent库的更新导致程序不能二进制兼容,因此,libevent提供了另外一个函数event_get_struct_event_sizel来获取event结构体的真实尺寸,以便实现程序在libevent的不同版本之间能够依然保持二进制兼容。

原型

int event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, event_callback_fn callback, void *callback_arg);

4.10 event_finalize

功能

告诉libevent在一个多线程环境中需要安全地关闭一个event事件。

备注

如果你构建event的时候用EV_FINALIZE标记来避免死锁的话,那么你需要一个方法来移除一个事件
并确保在释放事件及其回调参数时,事件绝对不会在运行其回调函数。

为了实现这个逻辑,调用一次event_finalize或者event_free_finalize,其中第一个参数设置为0,第二个参数是event事件的指针,第三个参数是回调函数(回调函数将作为事件循环的一部分而以event事件的优先级顺序被调用)。

当你完成对event_finalize或者event_free_finalized的调用以后,对这个event事件进行event_add或者event_active两个函数的操作将不再有效,并且event_del函数也将是一个空操作。当finalize回调正在进行的时候,你不能通过event_assign或者event_set尝试改变event事件的字段。一旦回调函数被调用,你应该认为event事件结构体指向的内存是未初始化状态的。

相对于event_finalize函数而言,其中event_free_finalize函数将在finalize结束后,释放event事件的内存。

finalizer回调函数不应该让event事件重新进入pending或者active状态,也就是说它不能通过event_add或者event_active函数的调用来复苏event事件。

原型

int event_finalize(unsigned, struct event *, event_finalize_callback_fn);

4.11 event_free_finalize

功能

告诉libevent在一个多线程环境中需要安全地关闭一个event事件,并且在finalize之后,释放event事件内存。

备注

参考event_finalize中的说明。

原型

int event_free_finalize(unsigned, struct event *, event_finalize_callback_fn);

4.12 event_remove_timer

功能

如果一个event在event_add的时候设置了超时,那么通过本函数可以取消超时定时器。但是不影响这个event本身的事件调度。

原型

int event_remove_timer(struct event *ev);

4.13 event_del_noblock

功能

和event_del一样,但是当待删除的事件的回调正在另外一个线程中运行的时候,不会产生阻塞,甚至该event事件的构建的时候没有用到EV_FINALIZE标记也是如此。

备注

原型

int event_del_noblock(struct event *ev);

4.14 event_del_block

功能

和event_del一样,但是当待删除的事件的回调正在另外一个线程中运行的时候,总是产生阻塞,甚至该event事件的构建的时候没有用到EV_FINALIZE标记也是如此。

备注

原型

int event_del_block(struct event *ev);

4.15 event_active

功能

手工激活一个event事件

备注

你可以对一个处于pedning或者非pending状态的event事件使用这个函数,来使这个事件进入active状态,这样子这个事件的回调函数将在事件循环中被调用。
在多线程程序中,本函数的一个常见的用法是用来从另外一个线程来唤醒正在执行event_base_loop的线程。

原型

void event_active(struct event *ev, int res, short ncalls);

4.16 event_initialized

功能

测试一个event事件结构体是否已经被初始化。

备注

这个函数仅用于区分已清零的内存块和已初始化的事件,它很容易被未初始化的内存所混淆。因此,它应该仅用于区分已初始化的事件和零值。

原型

int event_initialized(const struct event *ev);

4.17 event_get_fd

功能

获取一个event事件的文件句柄

备注

因为对于开发者来说,我们应该秉持看不到event结构体的完整定义的观念,这个是libevent本身的设计理念。如果我们包含了event2/event.h的头文件,可以看到下面的定义:

struct event
#ifdef EVENT_IN_DOXYGEN_
{/*Empty body so that doxygen will generate documentation here.*/}
#endif
;

libevent将event的所有内部定义都峰值到了内部,对于我们来说只需要知道event是一个结构体就可以了,而我们不能直接修改或者读取内部的数据,而必须通过libevent为我们提供的相关函数来进行操作。

原型

evutil_socket_t event_get_fd(const struct event *ev);

4.18 event_get_base

功能

获取一个event事件绑定的event_base指针

备注

原型

struct event_base *event_get_base(const struct event *ev);

4.19 event_get_events

功能

获取一个event事件上面实际监听的事件类型列表。

备注

注意,多个事件类型通过二进制位OR进行组合返回。

原型

short event_get_events(const struct event *ev);

4.20 event_get_callback

功能

获取一个event事件上面实际绑定的回调函数。

备注

原型

event_callback_fn event_get_callback(const struct event *ev);

4.21 event_get_callback_arg

功能

获取一个event事件上面实际绑定的回调函数的上下文参数。

备注

原型

void *event_get_callback_arg(const struct event *ev);

4.22 event_get_priority

功能

获取一个event事件的优先级值。

备注

原型

int event_get_priority(const struct event *ev);

4.23 event_get_assignment

功能

一次性提取所有在构建event的时候所设置的参数。

备注

如果希望获取某个参数,则将其设置为非NULL指针。

原型

void event_get_assignment(const struct event *event,struct event_base **base_out, evutil_socket_t *fd_out, short *events_out,event_callback_fn *callback_out, void **arg_out);

4.24 event_get_struct_event_size

功能

获取event事件结构体占用的内存大小。

备注

在手工进行event事件结构的内存分配的时候使用,为了避免不同版本的libevent之间的兼容性,不要使用sizeof(struct event)来获取event事件结构的占用的内存大小。

原型

size_t event_get_struct_event_size(void);

4.25 event_base_priority_init

功能

初始化设置event_base所支持的优先级队列的数量。

备注

原型

int event_base_priority_init(struct event_base *eb, int npriorities);

4.26 event_base_get_npriorities

功能

获取当前的event_base所设定的优先级队列的数量

备注

原型

int event_base_get_npriorities(struct event_base *eb);

4.27 event_priority_set

功能

为一个event事件设定优先级值。

备注

原型

int event_priority_set(struct event *ev, int priority);

4.28 event_set_mem_functions

功能

设置libevent进行内存管理的函数

备注

通过本函数的调用,可以将libevent内部进行内存分配、回收的相关函数替换为我们自定义的管理函数。

原型

void event_set_mem_functions(void *(*malloc_fn)(size_t sz),void *(*realloc_fn)(void *ptr, size_t sz),void (*free_fn)(void *ptr));

4.29 event_base_set

功能

将一个事件event重新绑定到一个新的event_base。

备注

需要确保当前正在被重新绑定的event没有在active或者pending状态中。

原型

int event_base_set(struct event_base *eb, struct event *ev);

4.30 event_gettime_monotonic

功能

获取当前单调递增的时间。

备注

原型

int event_gettime_monotonic(struct event_base *base, struct timeval *tp);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/873668.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Censot7 使用 yum 报错:Could not resolve host: mirrorlist.centos.org

解决方案:替换成阿里的镜像地址。 1:先备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 2:新建一个文件 touch /etc/yum.repos.d/CentOS-Base.repo 3:在新文件里写入以下内容 [base] name…

基于微信小程序图书馆座位预约系统设计与实现

链接: 文档和工程文件地址: ** 2、未完待续:请到目标位置下载 ** 链接: 文档和工程文件地址:

分布式搜索之Elasticsearch入门

Elasticsearch 是什么 Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集中存储您的数据,帮助您发现意料之中以及意料之外的情况。 Elastic Stack 又是什么呢&a…

排序系列 之 快速排序

!!!排序仅针对于数组哦本次排序是按照升序来的哦代码后边有图解哦 介绍 快速排序英文名为Quick Sort 基本思路 快速排序采用的是分治思想,即在一个无序的序列中选取一个任意的基准元素base,利用base将待排序的序列分…

【吊打面试官系列-ZooKeeper面试题】分布式集群中为什么会有 Master?

大家好,我是锋哥。今天分享关于 【分布式集群中为什么会有 Master?】面试题,希望对大家有帮助; 分布式集群中为什么会有 Master? 在分布式环境中,有些业务逻辑只需要集群中的某一台机器进行执行&#xff0c…

Leetcode1305.两颗二叉搜索树中的所有元素

1.题目要求: 给你 root1 和 root2 这两棵二叉搜索树。请你返回一个列表,其中包含 两棵树 中的所有整数并按 升序 排序。.2.思路: 我这个方法采用的是设立一个数组,然后用前序遍历把值存入数组中,然后用qsort给它排序 3.代码: /*** Definiti…

基本类型和包装类型的区别包装类型的缓存机制自动拆箱与自动装箱

基本类型和包装类型的区别是什么 存储方式:基本类型存储一般情况下储存在栈中(这里指的是局部变量),而基本类型的成员变量比如类的属性,会存储在堆之中。而包装类型我们都知道是引用类型存储在堆内存之中。 占用空间&…

[米联客-安路飞龙DR1-FPSOC] FPGA基础篇连载-21 VTC视频时序控制器设计

软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 板卡获取平台:https://milianke.tmall.com/ 登录“米联客”FPGA社区 ht…

蚂蚁集团推出EchoMimic:能通过音频和面部标志生成逼真的肖像动画视频

蚂蚁集团最近推出了一项名为EchoMimic的新技术。能通过音频和面部标志生成逼真的肖像动画视频,让你的声音和面部动作被完美复制到视频中,效果自然如照镜子。 EchoMimic不仅可以单独使用音频或面部标志点生成肖像视频,也可以将两者结合&#…

任意空间平面点云旋转投影至水平面—罗德里格旋转公式

1、背景介绍 将三维空间中位于任意平面上的点云数据,通过一系列的坐标变换(平移旋转),使其投影到XOY平面上,同时保证点云的几何中心与XOY平面的原点重合,同时点云形状保持不变。具体效果如下,具…

Vue中如何封装接口

在Vue项目中封装接口通常是指将HTTP请求(如GET、POST等)封装成可复用的函数或方法,以便于在组件中方便地调用。这样的封装有助于减少代码重复,增强代码的可维护性和可读性。以下是一个基于Vue和Axios(一个基于Promise的…

深入探究理解大型语言模型参数和内存需求

概述 大型语言模型 取得了显著进步。GPT-4、谷歌的 Gemini 和 Claude 3 等模型在功能和应用方面树立了新标准。这些模型不仅增强了文本生成和翻译,还在多模态处理方面开辟了新天地,将文本、图像、音频和视频输入结合起来,提供更全面的 AI 解…

MySQL MVCC原理

全称Multi-Version Concurrency Control,即多版本并发控制,主要是为了提高数据库的并发性能。 1、版本链 对于使用InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏列: 1、trx_id:每次一个事务对某条…

vue-treeselect

一、属性及属性值 属性类型默认值用途allowClearingDisabledBooleanfalse是否允许重置值,即使有禁用的选定节点allowSelectingDisabledDescendantsBooleanfalse 当选择/取消选择祖先节点时,是否应选择/取消选中其禁用的后代 可与allowClearingDisabled道…

Harbor系列之1:介绍、架构及工作流程说明

Harbor介绍、架构及工作流程说明 Harbor 是一个用于存储、签名和扫描内容的企业级容器镜像注册表项目。由 VMware 开发并于 2016 年开源。Harbor 提供了一些关键特性,使其成为企业使用的理想选择。 1. Harbor 介绍 1.1 什么是 Harbor Harbor 是一个开源的云原生…

UDP网口(1)概述

文章目录 1.计算机网络知识在互联网中的应用2.认识FPGA实现UDP网口通信3.FPGA实现UDP网口通信的方案4.FPGA实现UDP网口文章安排5.传送门 1.计算机网络知识在互联网中的应用 以在浏览器中输入淘宝网为例,介绍数据在互联网是如何传输的。我们将要发送的数据包称作A&a…

cordova使用vue进行开发

使用vue框架进行cordova跨平台混合框架app开发,步骤如下: 1、使用cordova创建一个项目 2、使用vue创建一个项目 3、在vue项目的根目录创建一个vue.config.js文件(如果有则不用再创建),vue.config.js的内容如下&…

Android 14 适配之 - 全屏 intent 通知

全屏 intent 通知 在 Android 11(API 级别 30)中,任何应用都可以在手机处于锁定状态时使用 Notification.Builder.setFullScreenIntent 发送全屏 intent。在 AndroidManifest 中声明 USE_FULL_SCREEN_INTENT 权限即可; 全屏 int…

在 ROS 2 中创建一个节点的过程

在 ROS 2 中创建一个节点的过程包括几个关键步骤。以下是一般的步骤流程,使用 C 和 ament_cmake 构建系统为例: 步骤 1: 创建工作空间 如果还没有工作空间,首先创建一个: mkdir -p ~/my_ros2_ws/src cd ~/my_ros2_ws colcon bu…

Java学习Day10:总结帖

学习第十天,发一个总结帖! 1.基本数据类型,变量 基本数据类型不用过多赘述,其在后面不论是面型对象还有其他知识等都会经常使用; 变量最重要的就是其定义: 这对于我们之后理解自定义类型变量有很大的用处…