天天看點

把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;
}      

繼續閱讀