User-Profile-Image
hankin
  • 5
  • 首页
  • 留言板
  • 贺卡
  • 密码本
  • 五码合一
  • 分类
    • 有感而发
    • 效率
    • 技术
    • 心境
    • 动漫
  • 页面
    • 留言板
  • 友链
    • 仙小宅
Help?

Please contact us on our email for need any support

Support
  • 首页
  • 留言板
  • 贺卡
  • 密码本
  • 五码合一
    首页   ›   技术   ›   正文
技术

C语言实现的多线程定时器

2021-01-02 23:08:00
9  0 0

目录

  • 1. 大致功能介绍
  • 2. API库介绍
  • 3. 一个例子
  • 4. 库文件源码
  • 注意事项

1. 大致功能介绍

  • 实现任务列表,定时器会间隔一段时间遍历列表发现要执行的任务
  • 任务列表中的所有任务并行执行
  • 每个任务都可以有自己的定时器,并且可以选择是否要重复执行
  • 定义方便的任务函数实现接口
  • 定时器可以由用户自定义何时启动和停止
  • 提供等待功能,保证任务列表中的所有任务执行完成
  • 提供任务列表的传参功能

2. API库介绍

void setTick(int val);

设置定时间的间隔时间tick,若设置tick为1000,且任务的定时器时间为1000,则任务会在1秒后执行,默认tick为1秒,最小tick时间为1us。

void addTimerTask(TimerTask task, int val, int autoreset, void *arg);

向任务列表注册一个任务,并指定其定时时间val,以及是否要重复执行autoreset,并可以指定参数的地址。
task需要按照头文件提供的宏来编写,例如:

TASK_START(test2, arg)

	//body
    Arg *temp = (Arg*)arg;
    temp->ret = temp->a + temp->b;
    printf("This is a test2\n");

TASK_END

TASK_START(name, arg)是任务头,name是任务名,arg是参数地址,TASK_END是任务结尾。任务体内可编写正常的c语言代码,并使用参数arg指针。
autoreset有两个可选项:AUTORESET(重复执行),NORESET(执行一次)。
若没有参数,可将arg参数设置为NULL。

void TimerWait();

用于等待任务列表中所有任务执行完毕。

void TimerStop();

用于停止定时器。

void StartTimer();

用于启动定时器。

3. 一个例子

#include <stdio.h>
#include "timer.h"

typedef struct Argument{
    int a;
    int b;
    int ret;
}Arg;

//任务1,打印语句
TASK_START(test1, arg)
    printf("This is a test1\n");
TASK_END

//任务2,计算arg中两个数的和,打印语句
TASK_START(test2, arg)

    Arg *temp = (Arg*)arg;
    temp->ret = temp->a + temp->b;
    printf("This is a test2\n");

TASK_END

//任务3,打印语句
TASK_START(test3, arg)
    printf("This is a test3\n");
TASK_END

void main(){

    Arg arg;

	//设置tick 为 500ms
    setTick(500 * 1000);

	//添加任务1到任务列表,设置定时器时间为2.5s,重复执行,无参数
    addTimerTask(test1, 5, AUTORESET, NULL);
    arg.a = 2; arg.b = 3;
    //添加任务2到任务列表,设置定时器时间为0.5s,不重复执行,参数为arg
    addTimerTask(test2, 1, NORESET, &arg);
    //添加任务3到任务列表,设置定时器时间为1s,重复执行,无参数
    addTimerTask(test3, 2, AUTORESET, NULL);

	//启动定时器
    StartTimer();
    printf("Timer is started\n");
    //程序等待5秒
    sleep(5);
    //停止定时器
    TimerStop();
    //等待所有任务执行完毕
    TimerWait();
    //打印任务二的计算结果
    printf("%d\n", arg.ret);

}

运行结果:

4. 库文件源码

timer.h:

#ifndef TIMER_H
#define TIMER_H

#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>

#define AUTORESET 1
#define NORESET   0

#define TASK_START(name, arg) void* name(void *arg){
#define TASK_END return NULL;} 

typedef void* (*TimerTask)(void* arg);

struct TaskItem{
    
    TimerTask task;
    int init_counter;
    int counter;
    pthread_t th;
    void *arg;
    void *ret;
    int flag;
    int autoreset;

    struct TaskItem *next;
    
};

void setTick(int val);

void* EventLoop(void* arg);

void addTimerTask(TimerTask task, int val, int autoreset, void *arg);

void TimerWait();

void TimerStop();

void StartTimer();


#endif //TIMER_H

timer.cpp

#include "timer.h"

#define STOPFLAG 0
#define RUNFLAG 1 

static int tick = 1000 * 1000;
static struct TaskItem head = {
    .next = NULL,
};
static pthread_t loop_thread;
static int flag = STOPFLAG;
static int tasknum  = 0;

void setTick(int val){
    tick = val;
}

void* EventLoop(void* arg){
    
    struct TaskItem *task = head.next;
    struct TaskItem *pretask = &head;

    while(flag == RUNFLAG && tasknum > 0){
        
        while(task != NULL){
            if(task->counter == 0){ // it is time for doing task
                if(task->flag == STOPFLAG){ // task is not created
                    if(0 != pthread_create(&(task->th), NULL, task->task, task->arg)){ // do a task
                        printf("Failed to create user's task");
                    }
                    else{
                        task->flag = RUNFLAG;
                    }
                }
                else{
                    if(0 != pthread_kill(task->th, 0)){ // current task is completed
                        if(task->autoreset == AUTORESET){ // repeat execute
                            task->counter = task->init_counter;
                            task->flag = STOPFLAG;
                        }
                        else{ // delete a task
                            pretask->next = task->next;
                            free(task);
                            task = pretask->next;
                            tasknum--;
                            continue;
                        }
                    }
                }
            }
            else{
                task->counter--;
            }
            pretask = pretask->next;
            task = task->next;
        }
        
        usleep(tick); // sleep a tick
        task = head.next;
        pretask = &head;

    }

    flag = STOPFLAG;

}

void addTimerTask(TimerTask task, int val, int autoreset, void *arg){
    struct TaskItem *node;

    node = (struct TaskItem*)malloc(sizeof(struct TaskItem));
    node->next = head.next;
    head.next = node;

    node->arg = arg;
    node->counter = val;
    node->init_counter = val;
    node->task = task;
    node->flag = STOPFLAG;
    node->autoreset = autoreset;

    tasknum++;

}

void TimerWait(){

    pthread_join(loop_thread, NULL);

}

void TimerStop(){
    flag = STOPFLAG;
}

void StartTimer(){
    
    flag = RUNFLAG;
    if(0 != pthread_create(&loop_thread, NULL, EventLoop, NULL)){
        printf("Failed to create loop task.\n");
    }

}


注意事项

  • 编译要加 -l pthread选项
  • 库实现在Linux环境,如果是windows需要修改线程创建函数,休眠函数以及相应的头文件。
  • 如有问题及建议可留言,另外创作不易,还望一键三连,多多支持博主,谢谢各位啦~~
评论 (0)

点击这里取消回复。

欢迎您 游客  

不羡江中仙
一叶一菩提,一花一世界
6446文章 8评论 14点赞 186417浏览

忆念

林深时见鹿,海蓝时见鲸,梦醒时见你。 可实际, 林深时雾起,海蓝时浪涌,梦醒时夜续。 未见鹿,未见鲸,亦未见你。 但, 鹿踏雾而来,鲸随浪而起,你没回头 又怎知我没来。

标签云
api asp c core docker github java js jvm kubernetes linux mysql net python redis seo spring springboot sql vite vue web 代码 优化 内存 函数 学习 对象 并发 按钮 接口 搜索引擎 数据 数据库 服务 服务器 模式 源码 算法 线程 组件 绑定 编程 网站 项目
近期文章
  • 决定 2021年1月23日
  • 使用node+puppeteer+express搭建截图服务_仙小宅_zip,程序 2021年1月4日
  • 【Go】四舍五入在go语言中为何如此困难_仙小宅_仙小宅,感情 2021年1月4日
  • 在 Emit 代码中如何await一个异步方法_仙小宅_仙小宅,python 2021年1月4日
  • 对各向异性高光的理解_仙小宅_版本升级,心理 2021年1月4日
文章归档
  • 2021年一月 (49)
  • 2020年十二月 (1)
  • 2020年十一月 (92)
  • 2020年十月 (140)
  • 2020年八月 (266)
  • 2020年七月 (987)
  • 2020年六月 (958)
  • 2020年五月 (716)
  • 2020年四月 (1137)
  • 2020年三月 (1133)
  • 2020年二月 (946)
  • 2020年一月 (2)
  • 2019年十二月 (19)
博客统计
  • 日志总数:6446 篇
  • 评论数目:8 条
  • 建站日期:2019-11-11
  • 运行天数:439 天
  • 标签总数:5341 个
  • 最后更新:2021-1-23
Copyright © 2021 网站备案号: 冀ICP备12010494号
主页
页面
  • 留言板
博主
不羡江中仙
不羡江中仙 管理员
不羡江中仙
6446 文章 8 评论 186417 浏览
测试
测试