libevent-Reactor设计模式【1】
一、Libevent概述
1、简介
Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大;源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。
Libevent 已经被广泛的应用,作为底层的网络库;比如 memcached、 Vomit、 Nylon、 Netchat等等。
二、两个重要的结构体
1、struct event
2、struct event_base
三、libevent常用接口
1、event_init( )函数:初始化事件集合
(1)函数原型
原型:struct event_base *event_init(void)
(2)函数实现
struct event_base *event_init(void)
{struct event_base *base = event_base_new_with_config(NULL);if (base == NULL) {event_errx(1, "%s: Unable to construct event_base", __func__);return NULL;}current_base = base;return (base);
}
(3)函数作用
初始化事件集合,其实就是调用了event_base_new_with_config( )函数,创建event_base对象,并且赋值给了全局变量struct evdns_base *current_base。
2、event_set( )函数:初始化事件
(1) 函数原型
原型:void event_set(struct event *ev, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg);
参数:
1)事件
2)关联的文件描述符
3)事件类型
4)回调函数
5)回调函数的参数
函数实现
void event_set(struct event *ev, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
{int r;r = event_assign(ev, current_base, fd, events, callback, arg);EVUTIL_ASSERT(r == 0);
}
(3)函数作用:
初始化event事件(其实就是给结构体ev的成员赋值)
fd
表示事件对应的文件描述符,events
表示事件的类型,callback
是回调函数(即当fd满足条件时调用该函数),arg
表示给回调函数传递的参数。
3、event_add( )函数:把事件添加到集合
(1)函数原型
原型:int event_add(struct event *ev, const struct timeval *tv);
int event_add(struct event *ev, const struct timeval *tv)
{int res;if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) {event_warnx("%s: event has no event_base set.", __func__);return -1;}EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);res = event_add_nolock_(ev, tv, 0);EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);return (res);
}
(3)函数作用
1.将event注册到event_base的I/O多路复用要监听的事件中;
2.将event注册到event_base的已注册事件链表中;
3.如果传入了超时时间,则删除旧的超时时间,重新设置,并将event添加到event_base的小根堆中;
如果没有传入超时时间,则不会添加到小根堆中。
只有步骤1成功,才会执行步骤2和3;否则什么都没做,直接返回,保证不会改变event的状态。
4、event_dispatch( )函数:监听事件
这个函数会让程序陷入死循环, 如果集合中没有事件可以监听,则返回
例子1:IO事件
- 1-fifo.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <event.h>
#include <fcntl.h>
/*当监听的事件满足条件的时候,会触发回调函数,通过回调函数读取数据*/
void fifo_read(evutil_socket_t fd, short events, void *arg) {char buf[32] = {0};int ret = read(fd, buf, sizeof(buf));if (-1 == ret) {perror("read");exit(1);} printf("从管道读取: %s\n", buf);
}int main() {int ret = mkfifo("fifo.tmp", 00700);if (-1 == ret) {perror("mkfifo");exit(1);}int fd = open("fifo.tmp", O_RDONLY);if (-1 == fd) {perror("open");exit(1);}// 创建事件struct event ev;// 初始化事件集合event_init();// 初始化事件(把fd和事件ev绑定)// 参数:事件、关联的文件描述符、事件类型、回调函数、回调函数参数event_set(&ev, fd, EV_READ | EV_PERSIST, fifo_read, NULL);//把事件添加到集合event_add(&ev, NULL);//开始监吿event_dispatch(); //死循玿 如果集合中没有事件可以监听,则返囿exit(0);
}
- 1-write_fifo.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>int main()
{int fd = open("fifo.tmp", O_WRONLY);if (-1 == fd) { perror("open");exit(2);} char buf[128] = {0};while (1){scanf("%s", buf);if (write(fd, buf, strlen(buf)) == -1){perror("write");break;}if (!strcmp(buf, "bye"))break;memset(buf, 0, 128);}close(fd);return 0;
}
运行结果:
5、event_base_new( )函数:创建事件集合
(1)函数原型
原型:struct event_base *event_base_new(void);
(2)函数实现
struct event_base *event_base_new(void)
{struct event_base *base = NULL;struct event_config *cfg = event_config_new();if (cfg) {base = event_base_new_with_config(cfg);event_config_free(cfg);}return base;
}
(3)函数作用
创建event_base对象
注意:采用event_base_new( )创建出来的事件集合,最后要用 event_base_free(base)释放掉,因为event_base_new( )是在堆空间上进行创建的。
(4)event_base_new( )与event_init( )的区别
这两个函数都会创建一个事件集合
event_init( )创建的是一个全局的事件集合
event_base_new( )创建的是一个局部的事件集合
event_init( )函数实现是由event_base_new( )封装而成的
6、event_base_free( )函数:释放事件集合
用于释放event_base_new( )函数创建的集合
7、event_assign( )函数:初始化事件
(1)函数原型:
原型:int event_assign(struct event *ev, struct event_base *base, evutil_socket_t fd, short events, void (*callback)(evutil_socket_t, short, void *), void *arg)
(2)参数介绍
1)事件
2)事件集合
3)关联的文件描述符
4)事件类型
5)回调函数
6)回调函数的参数
(3)函数作用
将指定事件集合中的事件与某一文件描述符进行关联
(4)event_assign( )与event_set( )的区别
event_assign( )可以指定事件集合;
event_set( )不能指定事件集合,默认采用event_init( )创建的全局的事件集合;
8、event_base_dispatch( )函数:监听事件
可监听事件集合当中的事件,和event_dispatch( )的作用相同
(1)event_base_dispatch( )与event_dispatch( )的区别
event_base_dispatch( )可以指定监听哪个事件集合;
event_dispatch( )不能指定事件集合,默认监听event_init( )创建的全局的事件集合;
9、event_del( )函数:把事件从集合中删除
原型:event_del(struct event *ev);
相关文章:

libevent-Reactor设计模式【1】
一、Libevent概述 1、简介 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大&#…...

奇奇怪怪的错误-Tag和space不兼容
报错信息如下: TabError: inconsistent use of tabs and spaces in indentation make: *** [Makefile:24: train] Error 1不能按Tab,要老老实实按space 不过可以在编辑器里面改,把它们调整成一致的;...

29.攻防世界ics-06
ics-06 难度:1 方向:Web 题目描述: 云平台报表中心收集了设备管理基础服务的数据,但是数据被删除了,只有一处留下了入侵者的痕迹。 进入靶场 发现有一处能点动 多了个id1 我其实尝试改过id数,不过没什么变化…...

强化学习路径规划:基于SARSA算法的移动机器人路径规划,可以更改地图大小及起始点,可以自定义障碍物,MATLAB代码
一、SARSA算法概述 SARSA(State-Action-Reward-State-Action)是一种在线强化学习算法,用于解决决策问题,特别是在部分可观测的马尔可夫决策过程(POMDPs)中。SARSA算法的核心思想是通过与环境的交互来学习一…...

【MFC】如何读取rtf文件并进行展示
tf是微软的一个带格式的文件,比word简单,我们可以用写字板等程序打开编辑。下面以具体实例讲解如何在自己程序中展示rtf文件。 首先使用VS2022创建一个MFC的工程。 VIEW类需要选择richview类,用于展示,如下图: 运行效…...

Vulhub:Log4j[漏洞复现]
CVE-2017-5645(Log4j反序列化) 启动靶场环境 docker-compose up -d 靶机IPV4地址 ifconfig | grep eth0 -A 5 ┌──(root㉿kali)-[/home/kali/Desktop/temp] └─# ifconfig | grep eth0 -A 5 eth0: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 in…...

面向预测性维护的TinyML技术栈全面综述
论文标题:A Holistic Review of the TinyML Stack for Predictive Maintenance(面向预测性维护的TinyML技术栈全面综述) 作者信息:Emil Njor, Mohammad Amin Hasanpour, Jan Madsen, Xenofon Fafoutis,均来自丹麦技术…...

沈阳理工大学《2024年811自动控制原理真题》 (完整版)
本文内容,全部选自自动化考研联盟的:《沈阳理工大学811自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题...

用前端html如何实现2024烟花效果
用HTML、CSS和JavaScript编写的网页,主要用于展示“2024新年快乐!”的文字形式烟花效果。下面是对代码主要部分的分析: HTML结构 包含三个<canvas>元素,用于绘制动画。引入百度统计的脚本。 CSS样式 设置body的背景为黑…...

Redis应用-在用户数据里的应用
1.社区电商的业务闭环 接下来介绍的社区电商是以Redis作为主体技术、以MySQL和RocketMQ作为辅助技术实现的。 (1)社区电商运作模式 社区电商的关键点在于社区,而电商则是辅助性质(次要地位,流量变现)。社区可以分成很多种社区,比如美食社区、美妆社区、影评社区、妈妈社区…...
C++ 中面向对象编程如实现数据隐藏
在C中,面向对象编程(OOP)通过封装(Encapsulation)来实现数据隐藏。封装是OOP的一个核心概念,它允许将对象的属性和行为(即数据和方法)组合在一起,并对外隐藏对象的内部实…...

JavaEE 【知识改变命运】04 多线程(3)
文章目录 多线程带来的风险-线程安全线程不安全的举例分析产出线程安全的原因:1.线程是抢占式的2. 多线程修改同一个变量(程序的要求)3. 原子性4. 内存可见性5. 指令重排序 总结线程安全问题产生的原因解决线程安全问题1. synchronized关键字…...
gz中生成模型
生成模型 通过服务调用生成 还记得parameter_bridge 吗? 我们在生成桥接的时候调用了这个cpp文件。 一个 parameter_bridge 实例用于消息传递(传感器数据)。之前的例子 另一个 parameter_bridge 实例用于服务桥接(动态生成模型…...
前端(Axios和Promis)
Promise 语法 <script>// 创建promise对象// 此函数需要再传入两个参数,都是函数类型let pnew Promise((resolve,reject)>{if(3>2){resolve({name:"李思蕾",age:23,地址:"河南省"});}else{reject("error");}});console.log(p);p.th…...

AI Agent:重塑业务流程自动化的未来力量(2/30)
《AI Agent:重塑业务流程自动化的未来力量》 摘要:整体思路是先介绍 AI Agent 的基本情况,再深入阐述其实现业务流程自动化的方法和在不同领域的应用,接着分析其价值和面临的挑战,最后得出结论,为读者全面…...
前端页面导出word
html-docx-js bug: vite使用html-docx.js会报错,点击下载上方文件替换即可 正文 npm install html-docx-js -S npm install file-saver -S<template><div id"managerReport">word内容......</div> </template><script>&l…...

【考前预习】1.计算机网络概述
往期推荐 子网掩码、网络地址、广播地址、子网划分及计算-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解,史上最全】-CSDN博客 浅学React和JSX-CSDN博客 浅谈云原生--微服务、CICD、Serverless、服务网格_云原生 serverless-CSDN博客 浅谈维度建模、数据分析…...

ubuntu20.04复现 Leg-KILO
这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录,例如 /opt/opencv-3.2:出错: 使用多线程编译错误1: stdlib.h: 没有那个文件或目录错误2:er…...

Ensembl数据库下载参考基因组(常见模式植物)bioinfomatics 工具37
拟南芥参考基因组_拟南芥数据库-CSDN博客 1 Ensembl数据库网址 http://plants.ensembl.org/index.html #官网 如拟南芥等 那么问题来了,基因组fa文件和gff文件在哪里? 2 参考案例 拟南芥基因组fa在这里 注释gff文件在这里...

简单介绍web开发和HTML CSS_web网站开发流程
一、Web 开发:探索互联网世界的基石 1.1 什么是 Web 开发 Web 开发,简单来说,就是构建能够通过浏览器访问的网站的过程。Web 代表着全球广域网,也就是我们熟知的万维网(www),它连接着世界各地的…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...

jdbc查询mysql数据库时,出现id顺序错误的情况
我在repository中的查询语句如下所示,即传入一个List<intager>的数据,返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致,会导致返回的id是从小到大排列的,但我不希望这样。 Query("SELECT NEW com…...