C语言实现定时器,定时触发函数

最近想到使用C语言实现一个简单的定时器。使用操作系统windows.h提供的多线程API就能实现
首先定义一个定时器结构体,包含定时时间和触发的函数指针

typedef struct Stimer{int valid;//定时器有效long timingMS;//定时时间TriggerFunc tf;//触发函数
}Stimer;

创建一个线程函数,用来运行定时器

DWORD WINAPI timer_thread(LPVOID lpParam){Stimer *st = (Stimer*)lpParam;long waitTime = st->timingMS;//获取定时间隔TriggerFunc tf = st->tf;//获取触发函数do{Sleep(waitTime);//休眠if(!st->valid){//判断定时器有效性break;}tf();//执行函数}while(1);
}

新建定时器的函数

Stimer* new_timer(){Stimer *st = malloc(sizeof(Stimer));st->valid = 0;st->timingMS = 0;st->tf = NULL;return st;
}

添加函数设置定时器的参数


void set_timer_timing(Stimer* st, long t){st->timingMS = t;
}
void set_timer_trigger_func(Stimer* st, TriggerFunc t){st->tf = t;
}

通过创建一个线程来运行定时器

void start_timer(Stimer* st){if(st->timingMS <= 0 || st->tf == NULL){return;}else{st->valid = 1;}//创建定时器线程DWORD threadID;HANDLE hThread = CreateThread(NULL,0,timer_thread,(LPVOID)st,0,&threadID);
}

对于定时器的停止,只需要改变它的有效标志


void stop_timer(Stimer* st){st->valid = 0;
}

定时器是动态分配的空间,最后需要添加一个释放定时器的函数


void release_timer(Stimer *st){free(st);
}

完整代码
timer.h

#ifndef _TIMER_H_
#define _TIMER_H_//定义函数指针类型
typedef void(*TriggerFunc)(void);
//定时器结构体
typedef struct Stimer{int valid;//定时器有效long timingMS;//定时时间TriggerFunc tf;//触发函数
}Stimer;
Stimer* new_timer();//新建定时器
void set_timer_timing(Stimer* st, long t);//设置定时器定时时间
void set_timer_trigger_func(Stimer* st, TriggerFunc t);//设置定时器触发函数
void start_timer(Stimer* st);//启动定时器
void stop_timer(Stimer* st);//停止定时器
void release_timer(Stimer *st);//销毁定时器
#endif // _TIMER_H_

timer.c

#include <windows.h>
#include "timer.h"
//定时器线程
DWORD WINAPI timer_thread(LPVOID lpParam){Stimer *st = (Stimer*)lpParam;long waitTime = st->timingMS;//获取定时间隔TriggerFunc tf = st->tf;//获取触发函数do{Sleep(waitTime);//休眠if(!st->valid){//判断定时器有效性break;}tf();//执行函数}while(1);
}
Stimer* new_timer(){Stimer *st = malloc(sizeof(Stimer));st->valid = 0;st->timingMS = 0;st->tf = NULL;return st;
}
void set_timer_timing(Stimer* st, long t){st->timingMS = t;
}
void set_timer_trigger_func(Stimer* st, TriggerFunc t){st->tf = t;
}
void start_timer(Stimer* st){if(st->timingMS <= 0 || st->tf == NULL){return;}else{st->valid = 1;}//创建定时器线程DWORD threadID;HANDLE hThread = CreateThread(NULL,0,timer_thread,(LPVOID)st,0,&threadID);
}void stop_timer(Stimer* st){st->valid = 0;
}
void release_timer(Stimer *st){free(st);
}

测试

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include "timer.h"
//测试函数
void test_func1(){puts("Function111 is executed");
}
void test_func2(){puts("Function222 is executed");
}
int main(){//创建2个定时器Stimer *st1 = new_timer();Stimer *st2 = new_timer();//设置定时器1set_timer_timing(st1, 400);//定时400msset_timer_trigger_func(st1, test_func1);//定时触发函数//设置定时器2set_timer_timing(st2, 600);set_timer_trigger_func(st2, test_func2);//运行定时器getch();puts("启动定时器1");start_timer(st1);getch();puts("启动定时器2");start_timer(st2);getch();puts("停止定时器1");stop_timer(st1);getch();puts("停止定时器2");stop_timer(st2);//销毁定时器release_timer(st1);release_timer(st2);getch();return 0;
}

结果
在这里插入图片描述
实现的定时器比较简单,没有对调用函数参数的支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据结构|二叉树遍历】递归与非递归实现前序遍历、中序遍历、后序遍历

递归与非递归实现二叉树的前序遍历、中序遍历、后序遍历。 二叉树图 定义 前序遍历&#xff08;Preorder Traversal&#xff09;&#xff1a; 前序遍历的顺序是先访问根节点&#xff0c;然后按照先左后右的顺序访问子节点。对于上面的二叉树&#xff0c;前序遍历的结果是&…

【FPGA IP系列】FIFO深度计算详解

FIFO(First In First Out)是一种先进先出的存储结构&#xff0c;经常被用来在FPGA设计中进行数据缓存或者匹配传输速率。 FIFO的一个关键参数是其深度&#xff0c;也就是FIFO能够存储的数据条数&#xff0c;深度设计的合理&#xff0c;可以防止数据溢出&#xff0c;也可以节省…

Stable Diffusion教程(8) - X/Y/Z 图表使用

1. 介绍 这项功能可以在 文生图/图生图 界面的左下角种 “脚本” 一栏内选择 “X/Y/Z 图表” 以启用。 它创建具有不同参数的图像网格。使用 X 类型和 Y 类型字段选择应由行和列共享的参数&#xff0c;并将这些参数以逗号分隔输入 X 值 / Y 值字段。支持整数、浮点数和范围。…

【AI】《动手学-深度学习-PyTorch版》笔记(七):自动微分

AI学习目录汇总 1、什么是自动微分 自动微分:automatic differentiation,深度学习框架通过自动计算导数,即自动微分,自动微分使系统能够随后反向传播梯度。 计算图:computational graph,根据设计好的模型,系统会构建一个计算图, 来跟踪计算是哪些数据通过哪些操作组合…

【工具使用】git基础操作1

目录 一.拉取git代码1.首次拉取命令2.使用图形化拉取代码3.Idea 开发工具拉取代码 二.查看当前状态1.查看在你上次提交之后是否有对文件进行再次修改 三.创建分支3.1.创建分支3.2.创建分支并切换至分支3.3.提交分支至远程仓 远程没有自动创建 四.查看分支4.1.查看本地分支 当前…

spring boot 2.x 使用 jpa 映射 json mysql列数据映射乱码

通过下面的依赖&#xff0c;可以将 mysql 的 json 列字段&#xff08;mysql 5.7及以上的版本支持&#xff09;&#xff0c;映射成 Java Bean <dependency><groupId>com.vladmihalcea</groupId><artifactId>hibernate-types-52</artifactId><v…

Python如何快速实现爬取网页?

首先我们对要编写的爬虫程序进行简单地分析&#xff0c;该程序可分为以下三个部分&#xff1a; 拼接 url 地址发送请求将照片保存至本地 明确逻辑后&#xff0c;我们就可以正式编写爬虫程序了。 导入所需模块 本节内容使用 urllib 库来编写爬虫&#xff0c;下面导入程序所用…

【iOS】json数据解析以及简单的网络数据请求

文章目录 前言一、json数据解析二、简单的网络数据请求三、实现访问API得到网络数据总结 前言 近期写完了暑假最后一个任务——天气预报&#xff0c;在里面用到了简单的网络数据请求以及json数据的解析&#xff0c;特此记录博客总结 一、json数据解析 JSON是一种轻量级的数据…

AP5179 高端电流采样降压恒流驱动IC SOP8 LED车灯电源驱动

产品描述 AP5179是一款连续电感电流导通模式的降压恒流源&#xff0c;用于驱动一颗或多颗串联LED输入电压范围从 5 V 到 60V&#xff0c;输出电流 最大可达 2.0A 。根据不同的输入电压和外部器件&#xff0c; 可以驱动高达数十瓦的 LED。内置功率开关&#xff0c;采用高端电流…

实验3-5 查询水果价格 (15 分)

实验3-5 查询水果价格 &#xff08;15 分&#xff09; 给定四种水果&#xff0c;分别是苹果&#xff08;apple&#xff09;、梨&#xff08;pear&#xff09;、桔子&#xff08;orange&#xff09;、葡萄&#xff08;grape&#xff09;&#xff0c;单价分别对应为3.00元/公斤、…

网络爬虫请求头中的Referer和User-Agent与代理IP的配合使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8EJgMcgK-1691050515642)(https://cdn.nlark.com/yuque/0/2023/png/1313150/1691048724422-2a76d7b8-3ec3-48b7-9aec-d609d09b16d4.png#averageHue%2385b0a7&clientIdu3856fd20-7701-4&fromui&…

PHP8的运算符-PHP8知识详解

运算符是可以通过给出的一或多个值&#xff08;用编程行话来说&#xff0c;表达式&#xff09;来产生另一个值&#xff08;因而整个结构成为一个表达式&#xff09;的东西。 PHP8的运算符有很多&#xff0c;按类型分有一元运算符、二元运算符、三元运算符。 一元运算符只对一…

选择适合的项目管理系统,了解有哪些选择和推荐

随着科技的进步和全球竞争的加剧&#xff0c;项目管理已经成为企业成功的关键要素。为了更好地组织和监控项目&#xff0c;许多企业和组织正在采用项目管理系统(PMS)。本文将探讨项目管理系统的主要组成部分以及其在实际应用中的优势。 “项目管理系统有哪些?国际上比较常见的…

侧边栏的打开与收起

侧边栏的打开与收起 <template><div class"box"><div class"sideBar" :class"showBox ? : controller-box-hide"><div class"showBnt" click"showBox!showBox"><i class"el-icon-arrow-r…

天气API强势对接

&#x1f935;‍♂️ 个人主页&#xff1a;香菜的个人主页&#xff0c;加 ischongxin &#xff0c;备注csdn ✍&#x1f3fb;作者简介&#xff1a;csdn 认证博客专家&#xff0c;游戏开发领域优质创作者,华为云享专家&#xff0c;2021年度华为云年度十佳博主 &#x1f40b; 希望…

分布式系统的 38 个知识点

天天说分布式分布式&#xff0c;那么我们是否知道什么是分布式&#xff0c;分布式会遇到什么问题&#xff0c;有哪些理论支撑&#xff0c;有哪些经典的应对方案&#xff0c;业界是如何设计并保证分布式系统的高可用呢&#xff1f; 1. 架构设计 这一节将从一些经典的开源系统架…

sqlite 踩坑

内存数据库 强制SQLite数据库单纯的存在于内存中的常用方法是使用特殊文件名“ &#xff1a;memory&#xff1a; ” db QSqlDatabase::addDatabase("QSQLITE", "MEMORY"); db.setDatabaseName(":memory:"); 调用此接口完成后&#xff0c;不…

P1629邮递员送信

邮递员送信 题目描述 有一个邮递员要送东西&#xff0c;邮局在节点 1 1 1。他总共要送 n − 1 n-1 n−1 样东西&#xff0c;其目的地分别是节点 2 2 2 到节点 n n n。由于这个城市的交通比较繁忙&#xff0c;因此所有的道路都是单行的&#xff0c;共有 m m m 条道路。这…

RISC-V基础指令之addi与lui(生成一个更大的立即数,包含负数符号拓展的特殊情况)

这两条指令都是RISC-V体系结构中的整数指令&#xff0c;它们的功能和格式如下&#xff1a; lui指令的全称是Load Upper Immediate&#xff0c;它的功能是把一个20位的立即数加载到寄存器的高20位&#xff0c;低12位为0。它的格式是&#xff1a; lui rd, imm 其中&#xff0c;rd…

spring boot 集成rocketmq

集成Spring Boot和RocketMQ 在现代的微服务架构中&#xff0c;消息队列已经成为一种常见的异步处理模式&#xff0c;它能解决服务间的同步调用、耦合度高、流量高峰等问题。RocketMQ是阿里巴巴开源的一款消息中间件&#xff0c;性能优秀&#xff0c;功能齐全&#xff0c;被广泛…