C语言定时任务库的实现(一)

目的

在项目开发过程中,我们常常需要定时的执行一些任务,通常的做法我们会创建一个线程,然后在线程里执行一个定时任务,如果有N个定时任务,则需要启动N个定时任务。这种做法有以下几个弊端。

1、频繁的创建线程可能会影响系统的整体运作性能。

2、每实现一个定时任务,则需要考虑任务的创建,销毁,任务的执行,而且大部分的内容是冗余的。

3、多任务之间的同步问题。

为了解决以上问题,我实现了一个多实例单线程多任务的定时器库。

实现方案

数据结构


typedef struct {
    struct list_head       head;                    // 链表头
    mtimer_task_callback   run;                     // 任务回调
    unsigned int        id;                         // 定时任务id
    unsigned int        last_tick;                  // 上一次执行的时间
    unsigned int        timeout;                    // 定时的超时时间,ms
    mtimer_task_mode    mode;                       // 定时任务的工作模式,两种工作模式。
    void           *user_data1;                     // 定时任务的上下文1
    void           *user_data2;                     // 定时任务的上下文2
    unsigned int        remove;                     // 定时任务是否标记删除
} mtimer_task;                                      // 定时任务节点

typedef struct {
    struct list_head    list;                       // 任务列表
    pthread_mutex_t  lock;                          // 锁
    unsigned int            id;                     // 待分配的定时器任务id
    mtimer_get_current_time get_current_time;       // 获取ms值的接口
} mtimer_handle;                                    // 定时器实例

工作模式

定时器有两种工作模式

typedef enum {
    MTIMER_MODE_LOOP = 0,        // 循环任务,每隔一个timeout执行一次
    MTIMER_MODE_NOT_LOOP,        // 非循环任务,仅在timeout时执行一次
} mtimer_task_mode;

接口

/*****************************************************************************
 函 数 名  : mtimer_create
 功能描述  : 创建定时器库实例
 输入参数  : mtimer_get_current_time func  
 输出参数  : 无
 返 回 值  : void
            NULL    : 创建失败
            非NULL   : 创建成功

*****************************************************************************/
void *mtimer_create(mtimer_get_current_time func);

/*****************************************************************************
 函 数 名  : mtimer_destroy
 功能描述  : 销毁定时器库实例
 输入参数  : void *handle  
 输出参数  : 无
 返 回 值  : int
            0   成功
            <0  失败

*****************************************************************************/
int mtimer_destroy(void *handle);

/*****************************************************************************
 函 数 名  : mtimer_task_reg
 功能描述  : 注册定时器任务
 输入参数  : void *handle                 
             mtimer_task_callback run  任务回调
             unsigned int    timeout   超时时间
             mtimer_task_mode    mode  LOOP:循环, 每隔timeout触发一次; NOT_LOOP:仅运行一次
             void       *user_data1    回调参数1
             void       *user_data2    回调参数2
 输出参数  : 无
 返 回 值  : unsigned
            返回定时器id

*****************************************************************************/
unsigned int mtimer_task_reg(
    void *handle,
    mtimer_task_callback run,
    unsigned int    timeout,
    mtimer_task_mode    mode,
    void       *user_data1,
    void       *user_data2);

/*****************************************************************************
 函 数 名  : mtimer_task_unreg
 功能描述  : 反注册定时器任务
 输入参数  : void *handle          
             unsigned int task_id   定时任务id  
 输出参数  : 无
 返 回 值  : 0: 反注册成功
            <0: 反注册失败

*****************************************************************************/
int mtimer_task_unreg(void *handle, unsigned int task_id);

/*****************************************************************************
 函 数 名  : mtimer_schedule
 功能描述  : 定时任务调度
 输入参数  : void *handle    
             unsigned int n  最多可执行的定时任务数,防止线程阻塞太长时间
 输出参数  : 无
 返 回 值  : 0  执行正常
            <0  执行异常

*****************************************************************************/
int mtimer_schedule(void *handle, unsigned int n);

使用范例

int func1(void *data1, void *data2)
{
    log_error("[time:%u, func1], data1:%s, data2:%s\n", Clock_GetTimeMs(),
              (char *)data1, (char *)data2);
    return 0;
}

int func2(void *data1, void *data2)
{
    log_error("[time:%u, func2], data1:%s, data2:%s\n", Clock_GetTimeMs(),
              (char *)data1, (char *)data2);
    return 0;
}

void *mtimer_debug_loop(void *handle)
{

    unsigned id1, id2;

    log_error("tick: %u------------------------------------ 1\n\n",
              Clock_GetTimeMs());
    id1 = mtimer_task_reg(handle, func1, 500, MTIMER_MODE_LOOP, "1data1", "1data2");
    id2 = mtimer_task_reg(handle, func2, 1000, MTIMER_MODE_NOT_LOOP, "2data1",
                          "2data2");
    while (1) {
        mtimer_schedule(handle, 10);
        Clock_SleepMs(100);
    }

    mtimer_destroy(handle);

    return NULL;
}

int mtimer_debug()
{
    void *handle;
    if (IS_NULL(handle = mtimer_create(Clock_GetTimeMs))) {
        log_error("mtimer_create failed\n");
        return -1;
    }

    pthread_t tid;
    pthread_create(&tid, NULL, mtimer_debug_loop, (void *)handle);
    pthread_detach(tid);

    return 0;
}

完整代码

代码还没有整理好,后续整理完之后会有更新,迫切需要的可以私聊

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值