libevent(7)libevent中的事件event

news2024/12/28 22:49:39

一、事件状态

libevent有4种事件状态,分别是: initialized、pending、active、persistent。这4种状态的转换关系如下:

1、已初始化(initialized):对应图中的non-pending状态,表示事件已经新建完成,但是还未添加到了libevent 队列中。有 4 种方法可以让事件跳转到此状态:

(1)调用 event_new 函数,返回一个事件对象,或调用 event_assign 赋值一个事件对象。

struct event *event_new(
    struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

int event_assign(struct event *, 
    struct event_base *, evutil_socket_t, short, event_callback_fn, void *);

// 回调函数指针定义
typedef void (*event_callback_fn)(evutil_socket_t, short, void *);

(2)pinding 状态的事件调用event_del函数后。

(3)active 状态的事件调用完成(即执行完事件回调函数),若没有定义持久化。

2、待决(pending):此状态表示事件已经位于libevent 队列中,可以随时准备执行。有 4 种方法可以让事件跳转到此状态:

(1)调用 event_add 之后。

(2)active 状态的事件调用完成(即执行完事件回调函数),若定义为持久化。

3、激活(active):此状态表示事件正在执行中,也包括超时事件。这是由 libevent 进行调度的,用户也可以手动调用 event_active 函数让事件转为此状态。

4、持久的(persistent):

(1)若定义为持久化,事件完成后状态会由 active 变为 pending ,可仍由 libevent 调用,不用做其他操作;

(2)若未定义为持久化,则表示事件完成后状态会由 active 变为 non-pending ,即初始化状态(initialized)。此时需要再次调用 event_add 函数,将事件变为 pending 状态,事件才会再次被执行。

二、例子

1、下面我们来看一个完整的例子 test_signal.cpp:


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

#define PORT 5001

using namespace std;

//socket 文件描述符
//which 事件类型
//arg 传递的参数 
static void Ctrl_C(int socket, short which, void* arg){
    cout<<"Ctrl_C"<<endl;
}

int main()
{   
    //创建libevent上下文
    event_base* base = event_base_new();
    if (base) {
        cout<<"event_base_new success!"<<endl;
    }

	//添加ctrl +c信号事件,处于no_pending状态
	event *csig = evsignal_new(base, SIGINT, Ctrl_C, base);
	if(!csig){
	    cerr<<"evsignal_new failed!"<<endl;
		return -1;
	}

	//添加事件到pending
	if(event_add(csig, 0) != 0){
	    cerr <<"event_add failed!"<< endl;
		return -1;
	}
	
    //事件分发处理
    if (base) {
        event_base_dispatch(base);
    }
	
    if (csig) {
	    event_free(csig);
	}
	
    if (base) {
        event_base_free(base);
    }

    return 0;
}

运行结果如下:

2、下面我们把这个例子再深化一下,添加下其他event:


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

#define PORT 5001

using namespace std;

//socket 文件描述符
//which 事件类型
//arg 传递的参数 
static void Ctrl_C(int socket, short which, void* arg){
    cout<<"Ctrl_C"<<endl;
}

static void Kill(int socket, short which, void* arg){
    cout<<"Kill"<<endl;
	
	//加上下面这段代码后,event又变被重新pending
	event* ev = (event*)arg;
	if(!evsignal_pending(ev, NULL)){
	    event_del(ev);
		event_add(ev, NULL);
	}
}

int main()
{   
    //创建libevent上下文
    event_base* base = event_base_new();
    if (base) {
        cout<<"event_base_new success!"<<endl;
    }

	//添加ctrl +c信号事件,处于no_pending状态
	//evsignal_new隐藏的状态: EV_SIGNAL|EV_PERSIST
	event *csig = evsignal_new(base, SIGINT, Ctrl_C, base);
	if(!csig){
	    cerr<<"evsignal_new csig failed!"<<endl;
		return -1;
	}

	//添加事件到pending
	if(event_add(csig, 0) != 0){
	    cerr <<"event_add csig failed!"<< endl;
		return -1;
	}
	
	//添加kill信号
	//EV_SIGNAL: 没有添加EV_PERSIST,表面当前event为非持久化事件,只能执行1次
	//event_self_cbarg(): 传递当前的event
	event *ksig = event_new(base, SIGTERM, EV_SIGNAL, Kill, event_self_cbarg());
	if(!ksig){
	    cerr<<"event_new ksig failed!"<<endl;
		return -1;
	}

	//添加事件到pending
	if(event_add(ksig, 0) != 0){
	    cerr <<"event_add ksig failed!"<< endl;
		return -1;
	}
	
    //事件分发处理
    if (base) {
        event_base_dispatch(base);
    }
	
    if (csig) {
	    event_free(csig);
	}
	
    if (base) {
        event_base_free(base);
    }

    return 0;
}

执行结果如下:

参考:

Libevent 学习四:事件状态和事件处理
https://blog.csdn.net/myw31415926/article/details/127372808

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

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

相关文章

细说设计模式

23种设计模式 &#xff08;一&#xff09;、创建型模式 对象实例化的模式&#xff0c;创建型模式用于解耦对象的实例化过程。 单例模式&#xff1a;某个类只能有一个实例&#xff0c;提供一个全局的访问点。工厂方法模式&#xff1a;一个工厂类根据传入的参量决定创建出哪一种…

AutoCMS全自动网站系统,供大家学习研究参考,商用请联系开发者!

AutoCMS全自动建站系统&#xff0c;只要一个关键词即可生成一个站&#xff0c;全自动建站、无需维护、无需数据库、无需安装&#xff0c;下载即用。支持在二级目录运行&#xff0c;丰富您的网站内容。 AutoCMS全自动网站使用说明 1.程序无需安装&#xff0c;解压该软件包之后&…

CSS的自定义属性var和JS的classList.toggle()方法,使用详细(css中var变量怎么应用)

简介&#xff1a;CSS中的var&#xff08;变量&#xff09;是CSS3中的新特性&#xff0c;用于定义可重用的值&#xff0c;类似于编程语言中的变量&#xff1b;它允许您在整个CSS文件中定义一个值&#xff0c;并在需要时使用该值。这样可以使CSS更加灵活和易于维护&#xff1b;cl…

VUE L 数据代理 ④

目录 文章有误请指正&#xff0c;如果觉得对你有用&#xff0c;请点三连一波&#xff0c;蟹蟹支持✨ V u e j s Vuejs Vuejs数据代理 什么是数据代理❓ 代理底层~ D e f i n e P r o p e r y DefinePropery DefinePropery V u e Vue Vue数据代理原理理解总结 文章有误…

第三方库介绍——libpng

文章目录 概述库版本的选择与下载安装zlib和libpng交叉编译交叉编译zlib库交叉编译libpng库 libpng的使用 概述 libpng是一款C语言编写的比较底层的读写PNG文件的跨平台的库。由于依赖于zlib库&#xff0c;所以在安装libpng时往往还需要安装zlib库。 库版本的选择与下载 zli…

积分等式与积分不等式

参考资料&#xff1a; B站 - 考研数学-积分不等式&#xff08;所有方法全归纳&#xff09;张宇基础和强化及习题册 积分等式 中值定理夹逼准则积分法 在这个专题中&#xff0c;有如下经验&#xff1a; 遇到 f ( x ) f(x) f(x)连续&#xff0c;应当想到变限积分 ∫ a x f ( t…

【软考网络管理员】2023年软考网管初级常见知识考点(6)- 虚拟局域网技术

涉及知识点 什么是虚拟局域网VLAN&#xff1f;VLAN的分类有哪些&#xff0c;IEEE802.1Q&#xff0c;VLAN的端口类型&#xff0c;VLAN信息的传递&#xff0c;软考网络管理员常考知识点&#xff0c;软考网络管理员网络安全&#xff0c;网络管理员考点汇总。 文章目录 涉及知识点…

单臂路由(RIP协议原理)

一、前言 1.1 本文为单臂路由&#xff08;RIP协议原理&#xff09;笔记 (供新手参考&#xff09; 通过RIP协议&#xff0c;交换机、单臂路由的工作原理和配置方法。 1.2 思科路由器设置ip设置 在将设备摆放完毕后&#xff0c;需要配置每台设备的IP&#xff0c;有如下三种基…

深入理解Java中的Lock和AQS

文章目录 前言正文一、Lock接口的定义二、ReentrantLock 的实现三、AbstractQueuedSynchronizer的实现3.1 AQS 中的加锁底层3.2 ReentrantLock中的 Sync 同步器3.3 NonfairSync 的实现3.4 FairSync 的实现3.5 公平锁和非公平锁的总结3.5.1 公平锁3.5.2 非公平锁 3.6 释放锁 前言…

突破边界:高性能计算引领LLM驶向通用人工智能AGI的创新纪元

AGI | AIGC | 大模型训练 | GH200 LLM | LLMs | 大语言模型 | MI300 ChatGPT的成功带动整个AIGC产业的发展&#xff0c;尤其是LLM&#xff08;大型语言模型&#xff0c;大语言模型&#xff09;、NLP、高性能计算和深度学习等领域。LLM的发展将为全球和中国AI芯片、AI服务器市场…

什么样的产品更适合做海外网红营销?

随着社交媒体和全球化的兴起&#xff0c;海外网红营销成为了一种非常受欢迎的推广方式。然而&#xff0c;并非所有产品都能够在海外市场成功借助网红营销实现推广目标。本文Nox聚星将和大家详细探讨什么样的产品更适合在海外进行网红营销&#xff0c;并提供相关的策略建议。 一…

汽车智能化进入赛点:城市NOA落地竞速,战至最后一公里

城市NOA的竞争正在加速进入落地阶段&#xff0c;6月即将结束&#xff0c;理想汽车计划在剩余几天内&#xff0c;在北京和上海开启城市辅助智能驾驶功能内测&#xff0c;并在下半年推出通勤智能驾驶功能。 其应用方法是&#xff0c;车主可用在日常使用中&#xff0c;基于智能化…

Linux系统编程(多进程编程深入1)

文章目录 前言一、进程参数和环境变量的意义二、子进程程序结束返回值到哪里去了&#xff1f;三、进程退出函数四、实际使用案例五、僵尸进程总结 前言 本篇文章我们深入的讲解多进程编程。 一、进程参数和环境变量的意义 进程参数和环境变量是两种不同的机制&#xff0c;但…

SuperMap GIS基础产品桌面GIS FAQ集锦(3)

SuperMap GIS基础产品桌面GIS FAQ集锦&#xff08;3&#xff09; 【iDesktop】如何获取倾斜摄影的边界线&#xff1f; 【解决办法】1、将倾斜摄影添加到球面场景&#xff0c;使用【三维分析】-【生成DSM】获取栅格数据集 2、使用【代数运算】功能&#xff0c;将大于0的栅格值统…

我做了10年的测试,由衷的建议年轻人别入这行了

两天前&#xff0c;有个做功能测试7年的同事被裁员了。这位老哥已经做到了团队中的骨干了&#xff0c;人又踏实&#xff0c;结果没想到刚刚踏入互联网“老龄化”大关&#xff0c;就被公司给无情优化了。 现在他想找同类型的工作&#xff0c;薪资也一直被压&#xff0c;考虑转行…

java(SpringBoot)中操作Redis的两种方式

前言 之前我们介绍过了redis的五中基本类型以及在可视化界面进行操作&#xff0c;那么在开发中&#xff08;在代码中&#xff09;我们通常使用&#xff0c;jedis进行操作redis,要是springboot 项目&#xff0c;我们通常使用redisTemplte进行操作 首先将redis启动 方式一 Jred…

smart Java——Netty实战(上):select/poll/epoll、NIOReactor模型

文章目录 1.多路复用——select、poll、epoll底层原理2.NIOReactor模型&#xff08;1&#xff09;单Reactor单线程模型&#xff08;2&#xff09;单Reactor多线程模型&#xff08;3&#xff09;主从Reactor多线程模型&#xff08;Netty&#xff09; 3.Netty核心组件&#xff08…

备战金九银十,互联网大厂1000道java高频面试知识点(附答案,赶紧收藏)

Java 面试八股文有必要背吗&#xff1f; 我的回答是&#xff1a;很有必要。你可以讨厌这种模式&#xff0c;但你一定要去背&#xff0c;因为不背你就进不了大厂。现如今&#xff0c;Java 面试的本质就是八股文&#xff0c;把八股文面试题背好&#xff0c;面试才有可能表现好。…

卷积实现—im2col+gemm

普通卷积 看卷积的实现&#xff0c;先看其普通的计算方式&#xff1a;滑窗计算和其计算shape大小的公式&#xff0c;以及各个卷积特性对其计算的影响&#xff0c;比如&#xff1a;stride&#xff0c;group&#xff0c;dilation&#xff0c;pad等。 H o u t ( H i n − k h p …

OpenGL 帧缓冲

1.简介 我们已经使用了很多屏幕缓冲了&#xff1a;用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许我们根据一些条件丢弃特定片段的模板缓冲。这些缓冲结合起来叫做帧缓冲(Framebuffer)&#xff0c;它被储存在内存中。OpenGL允许我们定义我们自己的帧缓冲&#x…