业务上有较多的定时运行功能,为了代码的通用性,自己实现一个简单的回调接口。
头文件如下:
#ifndef __MOD_TIMER_H__
#define __MOD_TTIMER_H__
#include "typedef.h"
typedef void (*mod_timer_task_callback)(void *data);
typedef u64 (*mod_timer_get_ms_callback)();
i32 mod_timer_init(mod_timer_get_ms_callback func);
void mod_timer_run();
//注意,执行回调函数有加锁,所以回调函数中不要有延时、休眠操作
//mode 0 无限循环,其他循环次数
u32 mod_timer_regist(u32 timeout, mod_timer_task_callback run, void *user_data, u32 mode);
void mod_timer_delete(u32 id);
#endif
具体实现如下:
#include "typedef.h"
#include "platform.h"
#include "list.h"
#include "mod_timer.h"
typedef struct
{
struct list_head list; // 链表
mod_timer_task_callback run; // 任务回调
u32 id; // 定时任务id
u64 lastMs; // 上一次执行的时间
u32 timeout; // 定时的超时时间,ms
u32 cnt; //循环次数,多次循环时使用
u32 mode; // 定时任务的工作模式,2种工作模式。初始化为0 则为循环模式,其他值则为循环次数
void *data; // 定时任务的上下文1
} ModTimerTask; // 定时任务节点
typedef struct
{
struct list_head list; // 任务列表
os_mutex lock; // 互斥锁,用于链表操作
mod_timer_get_ms_callback get_current_ms; // 获取ms值的接口
u32 id; //新任务注册时生成的id,依次增加
} ModTimerHandle; // 定时器实例
static ModTimerHandle timerHandle;
//定时器初始化
i32 mod_timer_init(mod_timer_get_ms_callback func)
{
INIT_LIST_HEAD(&timerHandle.list); // 链表初始化
timerHandle.get_current_ms = func;
os_mutex_init(&timerHandle.lock, NULL);
timerHandle.id = 1;
return 0;
}
//定时器轮询调度,由main函数调用
void mod_timer_run()
{
struct list_head *item;
struct list_head *next;
os_mutex_lock(&timerHandle.lock);
list_for_each_safe(item, next, &timerHandle.list)
{
ModTimerTask *task = list_entry(item, ModTimerTask, list);
u64 currentMs = timerHandle.get_current_ms();
if (((u32)(currentMs - task->lastMs) >= (u32)task->timeout))
{
if (task->run != NULL)
{
task->run(task->data);
}
task->lastMs = currentMs;
if (task->mode > 0)
{
task->cnt++;
if (task->cnt >= task->mode)
{
list_del(item);
}
}
}
}
os_mutex_unlock(&timerHandle.lock);
}
//注册定时任务
u32 mod_timer_regist(u32 timeout, mod_timer_task_callback run, void *user_data, u32 mode)
{
ModTimerTask *task = os_malloc(sizeof(ModTimerTask));
if (task == NULL)
{
return 0;
}
task->id = timerHandle.id++;
task->run = run;
task->lastMs = timerHandle.get_current_ms();
task->timeout = timeout;
task->cnt = 0;
task->mode = mode;
task->data = user_data;
os_mutex_lock(&timerHandle.lock);
list_add_tail(&task->list, &timerHandle.list);
os_mutex_unlock(&timerHandle.lock);
return task->id;
}
//删除定时任务
void mod_timer_delete(u32 id)
{
struct list_head *item;
struct list_head *next;
os_mutex_lock(&timerHandle.lock);
list_for_each_safe(item, next, &timerHandle.list)
{
ModTimerTask *task = list_entry(item, ModTimerTask, list);
if (task->id == id)
{
list_del(item);
}
}
os_mutex_unlock(&timerHandle.lock);
}
使用时现在main函数中调用mod_timer_init初始化定时器模块,需要传入一个取得本地时间(ms)的接口,然后在main函数的while(1)中调用mod_timer_run()。注册回调任务时调用:mod_timer_regist函数,第一个参数是定时时间(ms),第二个是回调函数,第三个是需要传给回调函数执行的参数,最后一个是模式,mode 0 无限循环,其他循环次数
mod_timer_regist(60 * 1000, gw_send_system_info_task, NULL, 0);
linux下取得毫秒函数为:
#include <unistd.h>
#include <sys/time.h>
u64 get_time_msec()
{
struct timeval val;
gettimeofday(&val, NULL);
return (u64)val.tv_sec * 1000 + (u64)val.tv_usec / 1000;
}
版权声明:本文为yeamon原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。