libevent学习——例子.md

news/2024/9/7 4:29:53 标签: 学习, c语言, libevent

time-test例子

第一个例子位于libevent源码libevent-2.1.12-stable/sample/time-test.c下面,是一个超时事件回调。

int
main(int argc, char **argv)
{
	struct event timeout;
	struct timeval tv;
	struct event_base *base;
	int flags;

#ifdef _WIN32
	WORD wVersionRequested;
	WSADATA wsaData;

	wVersionRequested = MAKEWORD(2, 2);

	(void)WSAStartup(wVersionRequested, &wsaData);
#endif

	if (argc == 2 && !strcmp(argv[1], "-p")) {
		event_is_persistent = 1;
		flags = EV_PERSIST;
	} else {
		event_is_persistent = 0;
		flags = 0;
	}

	/* Initialize the event library */
	base = event_base_new();

	/* Initialize one event */
	event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout);

	evutil_timerclear(&tv);
	tv.tv_sec = 2;
	event_add(&timeout, &tv);

	evutil_gettimeofday(&lasttime, NULL);

	setbuf(stdout, NULL);
	setbuf(stderr, NULL);

	event_base_dispatch(base);

	return (0);
}

从main函数看起

  1. 创建了三个变量:代表超时事件的timeout、存储时间的tv和用于管理事件的event_base结构体指针变量(使用指针是因为event_base结构体是一个库内部实现的结构体,对外只提供操作接口,不暴露实现细节)。
  2. 根据参数设置事件的flag(是否持久)。
  3. event_base_new():通过接口分配一个event_base结构体,同时也代表着事件库的初始化。
  4. event_assign:初始化timeout事件,指定管理事件的event_base、事件flag、事件触发的回调以及回调参数。
  5. event_add:添加事件并设置事件的超时事件。
  6. event_base_dispatch:开始事件循环,等待回调。
static void
timeout_cb(evutil_socket_t fd, short event, void *arg)
{
	struct timeval newtime, difference;
	struct event *timeout = arg;
	double elapsed;

	evutil_gettimeofday(&newtime, NULL);
	evutil_timersub(&newtime, &lasttime, &difference);
	elapsed = difference.tv_sec +
	    (difference.tv_usec / 1.0e6);

	printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
	    (int)newtime.tv_sec, elapsed);
	lasttime = newtime;

	if (! event_is_persistent) {
		struct timeval tv;
		evutil_timerclear(&tv);
		tv.tv_sec = 2;
		event_add(timeout, &tv);
	}
}

接着看回调,回调函数的类型都是固定的typedef void (*event_callback_fn)(evutil_socket_t, short, void *);

  1. 通过传给回调的参数arg获取到之前的event,因为在之前初始化timeout事件的时候将事件本身设置为了回调的参数。
  2. 计算事件触发时的时间并更新lasttime。
  3. 判断是否事件持久,如果事件持久,重新把事件添加到事件循环中。

signal-test例子

这个例子位于libevent-2.1.12-stable/sample/signal-test.c,是一个信号事件回调

int
main(int argc, char **argv)
{
	struct event *signal_int = NULL;
	struct event_base* base;
	int ret = 0;
#ifdef _WIN32
	WORD wVersionRequested;
	WSADATA wsaData;

	wVersionRequested = MAKEWORD(2, 2);

	(void) WSAStartup(wVersionRequested, &wsaData);
#endif

	/* Initialize the event library */
	base = event_base_new();
	if (!base) {
		ret = 1;
		goto out;
	}

	/* Initialize one event */
	signal_int = evsignal_new(base, SIGINT, signal_cb, event_self_cbarg());
	if (!signal_int) {
		ret = 2;
		goto out;
	}
	event_add(signal_int, NULL);

	event_base_dispatch(base);

out:
	if (signal_int)
		event_free(signal_int);
	if (base)
		event_base_free(base);
	return ret;
}

先看main函数

  1. 创建事件event和管理事件的event_base
  2. event_base_new:初始化事件库
  3. evsignal_new:初始化超时事件,虽然叫evsignal_new但本质是event_new创建事件
  4. event_add:添加信号事件
  5. event_base_dispatch:开启事件循环,等待信号事件回调
  6. 释放事件和事件管理器
static void
signal_cb(evutil_socket_t fd, short event, void *arg)
{
	struct event *signal = arg;

	printf("signal_cb: got signal %d\n", event_get_signal(signal));

	if (called >= 2)
		event_del(signal);

	called++;
}

接着看信号事件回调,很简单,就是打印信号并在第三次回调时删除事件


http://www.niftyadmin.cn/n/5083568.html

相关文章

redis 哨兵 sentinel(一)配置

sentinel巡查监控后台master主机是否故障,如果故障根据投票数自动将某一个从库转换为新主库,继续对外服务 sentinel 哨兵的功能 监控 监控主从redis库运行是否正常消息通知 哨兵可以将故障转移的结果发送给客户端故障转移 如果master异常,则…

Prometheus-Prometheus安装及其配置

Prometheus-Prometheus安装及其配置 Prometheus安装下载解压 配置启动prometheus校验配置文件表达式浏览器 Prometheus安装 Prometheus的安装针对Linux的安装,其他的安装方式可以查看Prometheus官网 下载 sudo wget https://github.com/prometheus/prometheus/re…

聊一聊 Spring 6 面向切面AOP

Java全能学习面试指南:https://javaxiaobear.cn 今天我们一起看看Spring AOP的相关操作! 1、场景模拟 搭建子模块:spring6-aop 1.1、声明接口 声明计算器接口Calculator,包含加减乘除的抽象方法 public interface Calculator…

【FreeRTOS】【STM32】04.0 FreeRTOS的使用1(创建单任务—SRAM静态内存)

我打算学习FreeRTOS时先学习如何使用它,然后再逐步展开。 RTOS 系统的核心就是任务管理 初步上手 RTOS 系统首先必须掌握任务的创建、删除、挂起和恢复等操作 任务三要素 任务主体函数,任务栈,任务控制块是一个任务的三要素 定义任务函数…

基于Vue构建的快速开发框架

一、Vue结合低代码 "低代码"是一种快速开发应用的方法,它使开发者能够通过图形界面和预构建的块进行设计和构建,而不是手动编写大量的代码。这种方法被广泛用于快速应用开发、移动应用开发、业务流程管理和数据库应用开发等领域。 Vue.js 是一…

一文了解 Go 接口

如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出 接口 在 Go 语言中,接口是一种抽象的类型,是一组方法的集…

如何使用 CloudQuery 对 100+ 套数据库进行安全管控?

业务挑战 A 集团信息部门发展将近 10 年,从最初的一个 MySQL 数据库到现在鱼龙混杂什么数据库都有,其中仓库部门用了 PostgreSQL 做数据底座,历史原因问题,生产系统却是使用 Oracle。基于信创的需求,上级领导要求试点…

物业巡检系统能做什么?物业服务如何提升管理效率?

随着科技的快速发展,物业管理行业也在寻求着更加高效、智能化的解决方案,以应对日益复杂的设备和环境巡检上的需求。目前传统的纸质巡检方式已经无法满足现代物业管理的要求,“的修”工单管理系统应运而生,它通过数字化、智能化的…