把libevent 2.1.8源码的最小堆提取出来,自己封装成定时器使用(2)(★firecat推荐★)

简介: 把libevent 2.1.8源码的最小堆提取出来,自己封装成定时器使用(2)(★firecat推荐★)

4、my_timer.h

#ifndef MY_TIMER_H
#define MY_TIMER_H
#define LIMIT_TIMER 1 //有限次数定时器
#define CYCLE_TIMER 2 //循环定时器
extern "C"
{
#include "minheap-internal.h"
}
class Timer
{
public:
    Timer();
    virtual ~Timer();
    /**************************************
     * input: interval: 每次执行的时间隔间, 单位是毫秒。
     *        fun arg : 回调函数以及参数。
     *        flag    : 循环定时器还是有限次数定时器,如果是相对定时器
     *        exe_num : 只有在有限次数定时器才有效,表示执行的次数。最少为1次
     * return: 生成定时器的ID
     **************************************/
    unsigned int timer_add(int interval, void (*fun)(void*), void *arg,  int flag = CYCLE_TIMER,
                           int exe_num = 0);
    /***************************************
     * description:
     * 去掉已经加入的定时器,比如产生定时器的母体已经消亡了,在消亡之间要将其删除。
     * 相对定时器在任务完成后会Timer会自己释放掉。
     ***************************************/
    bool timer_remove(unsigned int timer_id);
    /***************************************
     * description: Timer属于被动对象,没有自己的执行线程,属于被调用者。这样主要是为了避免产生线程同步。
     * 定时器的循环处理函数,由定时器的拥有者进行循环调用。它的最小时间间隔决定了定时器的精度。
     ***************************************/
    int timer_process();
private:
    struct min_heap _min_heap;
    unsigned int _timer_id;
};
#endif // MY_TIMER_H


5、my_timer.cpp

#include "my_timer.h"
Timer::Timer() :
    _timer_id(0)
{
    min_heap_ctor_(&_min_heap);
}
Timer::~Timer()
{
    for (int i = 0; i < _min_heap.n; i++)
    {
        free(_min_heap.p[i]);
    }
    min_heap_dtor_(&_min_heap);
}
unsigned int Timer::timer_add(int interval, void(*fun)(void*), void *arg,
                              int flag /* = CYCLE_TIMER */, int exe_num /* =  0 */)
{
    struct event * ev = (struct event*) malloc(sizeof(struct event));
    min_heap_elem_init_(ev);
    if (NULL == ev)
        return NULL;
    struct timeval now;
    gettime(&now);
    ev->ev_interval.tv_sec = interval / 1000;
    ev->ev_interval.tv_usec = (interval % 1000) * 1000;
    evutil_timeradd(&now, &(ev->ev_interval), &(ev->ev_timeout));
    ev->ev_flags = flag;
    ev->ev_callback = fun;
    ev->ev_arg = arg;
    ev->ev_exe_num = exe_num;
    ev->timer_id = _timer_id++;
    min_heap_push_(&_min_heap, ev);
    return ev->timer_id;
}
bool Timer::timer_remove(unsigned int timer_id)
{
    for (int i = 0; i < _min_heap.n; i++)
    {
        if (timer_id == _min_heap.p[i]->timer_id)
        {
            struct event * e = _min_heap.p[i];
            min_heap_erase_(&_min_heap, _min_heap.p[i]);
            free(e);
            return true;
        }
    }
    return false;
}
int Timer::timer_process()
{
    struct event *event;
    struct timeval now;
    while ((event = min_heap_top_(&_min_heap)) != NULL)
    {
        gettime(&now);
        if (evutil_timercmp(&now, &(event->ev_timeout), < ))
            break;
        min_heap_pop_(&_min_heap);
        event->ev_callback(event->ev_arg);
        if (event->ev_flags == CYCLE_TIMER
                || (event->ev_flags == LIMIT_TIMER && --event->ev_exe_num > 0))
        {
            evutil_timeradd(&(event->ev_timeout), &(event->ev_interval), &(event->ev_timeout));
            min_heap_push_(&_min_heap, event);
        }
        else
        {
            free(event);
        }
    }
    return 0;
}

6、main.cpp


#include <iostream>
#include "my_timer.h"
#include <unistd.h>
using namespace std;
static void fun(void *arg)
{
   int *id = (int *) arg;
   cout << *id << endl;
}
int main()
{
    cout << "Hello World!" << endl;
    Timer t;
    int id1 = 100;
    t.timer_add(1000, fun, &id1);//ms
    int id2 = 101;
    t.timer_add(5000, fun, &id2);
    int id3 = 102;
    t.timer_add(3000, fun, &id3);
    while (true)
    {
        t.timer_process();
        sleep(1);
    }
    system("pause");
    return 0;
}


相关文章
|
Java 调度 Maven
Elastic-job分布式调度系统
Elastic-job分布式调度系统
293 2
|
存储 安全 开发工具
oss加密存储
阿里云OSS为数据安全提供多种加密机制,包括服务器端的SSE-S3(AES-256透明加密)、SSE-C(用户管理密钥)和CSE-KMS(结合KMS进行密钥管理)。此外,OSS支持客户端加密SDK和HTTPS传输加密,确保数据在传输和存储时的安全。通过ACL、Bucket策略和访问密钥身份验证,实现权限控制与身份验证,全方位保障用户数据的安全性和隐私。用户可按需选择适合的加密方式。
1207 2
|
算法
最小生成树算法:Prim算法
在图论中,最小生成树(Minimum Spanning Tree,简称MST)是一种常用的算法问题。最小生成树是指在一个加权连通图中选取边的子集,使得所有顶点都被覆盖,并且边的总权值最小。
1489 0
|
人工智能 测试技术 API
通义灵码 + 魔搭MCP:全流程构建创空间应用
最近,通义灵码上线 MCP(ModelScope Cloud Platform)功能,从之前代码生成及修改的基础功能,到可以使用MCP服务连接更多功能,开发者可以实现从 代码爬取、模型推理到应用部署
3140 27
|
存储 缓存 Linux
【实战指南】用最小堆实现通用的高效定时器组件
本文介绍了如何使用最小堆实现高效的定时器组件,以解决Linux应用开发中定时器资源有限的问题。文章详细描述了最小堆方式的实现原理,包括系统定时器、定时器任务和定时器任务管理三个类的设计与源码实现。测试结果显示,该方法能够准确触发定时任务,有效利用系统资源。总结部分强调了使用最小堆的优势,以及通过抽象类实现清晰的业务逻辑。
613 96
|
运维 监控 Devops
自动化运维实践:打造高效的DevOps流水线
在软件开发的快节奏中,自动化运维成为提升效率、确保质量的关键。本文将引导你理解自动化运维的价值,通过实际案例分享如何构建一个高效、可靠的DevOps流水线。我们将从持续集成(CI)开始,逐步深入到持续部署(CD),并展示代码示例来具体说明。准备好让你的运维工作飞跃式进步了吗?让我们开始吧!
|
机器学习/深度学习 安全 算法框架/工具
开源vs闭源,大模型的未来在哪一边?
开源vs闭源,大模型的未来在哪一边?
1106 0
开源vs闭源,大模型的未来在哪一边?
|
移动开发 算法
秒懂算法 | A*搜索
本篇内容包括了A*搜索算法的原理精解以及2个例题。
1464 1
秒懂算法 | A*搜索
|
Ubuntu
修改虚拟机Ubuntu为桥接模式的静态IP
修改虚拟机Ubuntu为桥接模式的静态IP
1646 0
|
对象存储
统计数组中的重复数据的数量
这篇文章总结了5种统计数组中重复数据数量的方法。方法1和4使用for循环和对象存储计数;方法2和5利用`reduce`函数,其中方法5是最简写形式;方法3是特定场景下的应用,针对特定值计数。所有方法最终都返回一个对象,键为数组元素,值为出现次数。
940 3