从0到1掌握libhv定时器:让你的任务调度如丝般顺滑

从0到1掌握libhv定时器:让你的任务调度如丝般顺滑

【免费下载链接】libhv 🔥 比libevent/libuv/asio更易用的网络库。A c/c++ network library for developing TCP/UDP/SSL/HTTP/WebSocket/MQTT client/server. 【免费下载链接】libhv 项目地址: https://gitcode.com/gh_mirrors/li/libhv

你是否还在为网络编程中的定时任务调度烦恼?定时器不准、内存泄漏、复杂任务难以管理?本文将带你全面掌握libhv网络库中定时器回调的使用方法,从基础API到高级任务调度,让你的定时任务处理既高效又可靠。读完本文,你将能够轻松实现单次定时、周期性任务、Cron风格调度等功能,并了解多线程环境下的定时器安全使用技巧。

定时器基础:核心数据结构与API

libhv的定时器功能主要通过hloop_t事件循环和htimer_t定时器对象实现,相关定义位于event/hloop.h头文件中。

核心数据类型

  • hloop_t: 事件循环对象,负责管理所有定时器事件的注册、触发和销毁
  • htimer_t: 定时器对象,代表一个具体的定时任务
  • htimer_cb: 定时器回调函数类型,定义为void (*htimer_cb)(htimer_t* timer)

基础API概览

// 创建定时器
htimer_t* htimer_add(hloop_t* loop, htimer_cb cb, uint32_t timeout_ms, uint32_t repeat);

// 删除定时器
void htimer_del(htimer_t* timer);

// 重置定时器
void htimer_reset(htimer_t* timer, uint32_t timeout_ms);

其中timeout_ms参数指定定时时间(毫秒),repeat参数指定重复次数(INFINITE表示无限重复)。

快速上手:第一个定时器程序

让我们从一个简单的示例开始,创建一个每隔1秒触发一次的定时器。完整代码可参考examples/htimer_test.c

单次定时器

#include "hloop.h"

// 定时器回调函数
void on_timer(htimer_t* timer) {
    printf("定时器触发!当前时间: %llu ms\n", hloop_now_ms(hevent_loop(timer)));
}

int main() {
    // 创建事件循环
    hloop_t* loop = hloop_new(0);
    
    // 添加定时器:3秒后触发,仅执行一次
    htimer_add(loop, on_timer, 3000, 1);
    
    // 运行事件循环
    hloop_run(loop);
    
    // 释放资源
    hloop_free(&loop);
    return 0;
}

周期性定时器

要创建周期性定时器,只需将repeat参数设为INFINITE

// 添加周期性定时器:每隔1秒触发一次
htimer_add(loop, on_timer, 1000, INFINITE);

编译与运行

使用Makefile编译示例程序:

make examples
./examples/htimer_test

运行后,你将看到定时器按预期触发。

高级功能:Cron风格调度

libhv提供了类似Cron的定时任务调度功能,通过htimer_add_period函数实现,可以按分钟、小时、日、周、月等周期调度任务。

Cron API定义

htimer_t* htimer_add_period(hloop_t* loop, htimer_cb cb,
                           int8_t minute, int8_t hour, int8_t day,
                           int8_t week, int8_t month, uint32_t repeat);

参数说明:

  • minute: 分钟 (0-59)
  • hour: 小时 (0-23)
  • day: 日 (1-31)
  • week: 星期 (0-6, 0表示周日)
  • month: 月 (1-12)
  • repeat: 重复次数

实用示例

// 每小时触发一次(整点触发)
htimer_add_period(loop, cron_hourly, 0, -1, -1, -1, -1, INFINITE);

// 每天凌晨3点30分触发
htimer_add_period(loop, daily_task, 30, 3, -1, -1, -1, INFINITE);

// 每周五下午4点触发
htimer_add_period(loop, weekly_task, 0, 16, -1, 5, -1, INFINITE);

examples/htimer_test.c中提供了完整的Cron风格调度示例,你可以参考学习。

定时器管理:删除与重置

在实际应用中,我们经常需要动态管理定时器,如取消定时任务或调整定时时间。

删除定时器

// 创建定时器并保存句柄
htimer_t* timer = htimer_add(loop, on_timer, 1000, INFINITE);

// 在需要时删除定时器
htimer_del(timer);

重置定时器

// 重置定时器为2秒后触发
htimer_reset(timer, 2000);

// 如果timeout_ms为0,则使用原来的间隔
htimer_reset(timer, 0);

下面是一个重置定时器的完整示例:

void on_timer_reset(htimer_t* timer) {
    static int count = 0;
    printf("第%d次触发,即将重置定时器\n", ++count);
    
    if (count >= 5) {
        // 5次后重置为3秒间隔
        htimer_reset(timer, 3000);
        printf("定时器已重置为3秒间隔\n");
    }
}

// 在main函数中
htimer_add(loop, on_timer_reset, 1000, INFINITE);

高级应用:定时器优先级与多线程安全

libhv定时器支持设置优先级,可用于实现任务的分级调度。同时,libhv保证了定时器操作的线程安全性。

设置定时器优先级

htimer_t* timer = htimer_add(loop, on_timer, 1000, INFINITE);
hevent_set_priority(timer, HEVENT_HIGH_PRIORITY); // 设置高优先级

优先级取值范围从HEVENT_LOWEST_PRIORITY(-5)到HEVENT_HIGHEST_PRIORITY(5),默认为HEVENT_NORMAL_PRIORITY(0)。

多线程环境下使用

在多线程环境中,可以安全地调用htimer_addhtimer_delhtimer_reset函数。如果需要从其他线程触发定时器事件,可以使用hloop_post_event函数:

// 在工作线程中发送事件到事件循环线程
hevent_t ev;
memset(&ev, 0, sizeof(ev));
ev.loop = loop;
ev.cb = on_custom_event;
ev.userdata = "来自工作线程的消息";
hloop_post_event(loop, &ev);

实战技巧:定时器常见问题解决方案

避免回调函数阻塞

定时器回调函数应尽快执行完毕,避免阻塞事件循环。如果需要执行耗时操作,建议将其放入线程池处理:

#include "hthreadpool.h"

void long_running_task(void* arg) {
    // 耗时操作...
}

void on_timer(htimer_t* timer) {
    // 将耗时任务提交到线程池
    hthreadpool_post(hthreadpool_get_global(), long_running_task, NULL);
}

定时器精度控制

libhv使用系统时钟实现定时器,精度通常在毫秒级别。如果需要更高精度的定时,可以考虑使用hloop_now_hrtime函数获取高精度时间戳进行补偿。

void on_precise_timer(htimer_t* timer) {
    static uint64_t last_time = 0;
    uint64_t now = hloop_now_hrtime(hevent_loop(timer));
    if (last_time > 0) {
        printf("实际间隔: %llu us\n", now - last_time);
    }
    last_time = now;
}

总结与进阶学习

通过本文的介绍,你已经掌握了libhv定时器的基本使用方法和高级特性。libhv定时器模块以其简洁的API和可靠的性能,为网络应用中的任务调度提供了强大支持。

进阶学习资源

下一步

尝试使用libhv定时器实现以下功能:

  1. 实现一个定时日志轮转器
  2. 使用Cron风格定时器实现每日数据备份
  3. 结合网络模块实现定时心跳检测

希望本文能帮助你更好地利用libhv的定时器功能,构建高效可靠的网络应用!如果你有任何问题或建议,欢迎在项目仓库中提交issue。

【免费下载链接】libhv 🔥 比libevent/libuv/asio更易用的网络库。A c/c++ network library for developing TCP/UDP/SSL/HTTP/WebSocket/MQTT client/server. 【免费下载链接】libhv 项目地址: https://gitcode.com/gh_mirrors/li/libhv

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值