实现定时器的两种方法:使用windows api定时器 和使用c++11/14 定时器

前言:

当我有一个开发需求,符合下面的条件

1.需要某个任务在程序中每隔一段时间就要执行一次,可能把这个任务封装成了一个函数。

2.这种需要定时执行的任务,有2个,3个....越来越多

这个时候我们就可以考虑使用定时器,把这种任务封装成函数,放进定时器中。每隔一段时间会自动帮我们执行该任务。

1.windows api定时器

主要是使用了两个windows api 函数,来实现定时器的效果

SetTimer函数和KillTimer函数

/*
 * Windows Functions
 */

WINUSERAPI
UINT_PTR
WINAPI
SetTimer(
    _In_opt_ HWND hWnd, //窗口句柄
    _In_ UINT_PTR nIDEvent,//注册的对应任务的ID,
    _In_ UINT uElapse, //设置的每次执行该回调函数的时间间隔,单位是毫秒
    _In_opt_ TIMERPROC lpTimerFunc); //注册的对应任务的回调函数,

删除某个定时器里面的任务。

WINUSERAPI
BOOL
WINAPI
KillTimer(
    _In_opt_ HWND hWnd, // 窗口句柄
    _In_ UINT_PTR uIDEvent); //对应的定时任务的id

来一个实际的Demo:

#include <iostream>
#include <Windows.h>

using namespace std;


void CALLBACK Task1(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
{
	cout << "task1" << endl;
}

void CALLBACK Task2(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
{
	cout << "task2" << endl;
}


void main()
{

	MSG msg;
	SetTimer(NULL, 111, 1000, (TIMERPROC)Task1);
	SetTimer(NULL, 112, 1000, (TIMERPROC)Task2);
	//消息死循环,一直监听键盘的输入,然后把消息发送到主程序窗口
	//我们按下ctrl + c的时候,程序会自动停止
	while (GetMessage(&msg, NULL, NULL, NULL))
	{
		if (msg.message == WM_TIMER)
		{
			TranslateMessage(&msg); //把键盘字符,转换成协议消息
			DispatchMessage(&msg);//把消息命令发送到主窗口
		}
	}

	KillTimer(NULL, 111);
	KillTimer(NULL, 112);
}

输出打印结果:

过程说明:

windows主程序中已经帮我们写好了一个定时器的组件。

我们只需要把我们要执行的任务,封装成回调函数。

然后通过SetTimer把这个函数注册进去就行。

通过KillTimer把某个任务删掉就行。

2.c++11/14 实现定时器----简易定时器

有两种定时器:

1.每天的固定时间执行一次任务。

2.间隔一段时候执行一任务。

task_timer.h

#pragma once

#include <iostream>
#include <thread>
#include <functional>
#include <ctime>
class TaskTimer {
public:
	TaskTimer() {};
	~TaskTimer() {};
private:
	void ThreadInterval(int interval, std::function<void()> task)
	{
		while (!stop_sign)
		{
			task();
			std::chrono::milliseconds dura(interval);	//间隔几秒
			std::this_thread::sleep_for(dura);
		}
	}

	void ThreadFixedTime(struct tm time_data, std::function<void()> task)
	{
		time_t t = time(nullptr);
		struct tm nowTime;
	
		while (!stop_sign)
		{
			t = time(nullptr);
			localtime_s(&nowTime, &t);
			//std::cout << nowTime.tm_hour << " " << nowTime.tm_min << " " << nowTime.tm_sec << " " << std::endl;
			if (time_data.tm_hour == nowTime.tm_hour && time_data.tm_min == nowTime.tm_min && time_data.tm_sec == nowTime.tm_sec)
			{
				task();
			}
			std::chrono::milliseconds dura(900);	
			std::this_thread::sleep_for(dura);
		}
	}

public:
	//添加一个任务间隔一段时间执行一次
	void AddTaskInterval(int interval, std::function<void()> task)
	{
		std::thread( &TaskTimer::ThreadInterval, this, interval, task).detach();
	}
	//添加一个任务,在每天的固定时间执行
	void AddTaskFixedTime(struct tm time_data, std::function<void()> task)
	{
		std::thread(&TaskTimer::ThreadFixedTime, this, time_data, task).detach();
	}
	//停止定时器
	void StopTaskInterval()
	{
		stop_sign = true;
	}

	

private:
	std::atomic<bool> stop_sign = false;
};

main.cpp

#include <iostream>
#include "task_timer.h"
void func1()
{
	std::cout << "func1\n" << std::endl;
}


void func2()
{
	std::cout << "func2\n" << std::endl;
}


int main(int argc, char* argv[])
{
	TaskTimer timer;
	//timer.AddTaskInterval(1000, func1);
	//timer.AddTaskInterval(1000, func2);
	struct tm time_data;
	time_data.tm_hour = 17;
	time_data.tm_min = 14;
	time_data.tm_sec = 58;
	timer.AddTaskFixedTime(time_data, func1);
	timer.AddTaskFixedTime(time_data, func2);
	getchar();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web基础03-JavaScript

目录 一、JavaScript基础 1.变量 2.输出 3.变量提升 4.区块 5.JavaScript数据类型 6.查看数值类型 7.undefined和null 8.布尔值 9.和的区别 10.算数/三元/比较/逻辑/赋值运算符 11.特殊字符 12.字符串 &#xff08;1&#xff09;获取字符串长度 &#xff08;2&am…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的番茄成熟度检测系统(Python+PySide6界面+训练代码)

摘要&#xff1a;开发番茄成熟度检测系统对于提高农业产量和食品加工效率具有重大意义。本篇博客详细介绍了如何利用深度学习构建一个番茄成熟度检测系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并结合了YOLOv7、YOLOv6、YOLOv5的对比&…

SpringBoot约定大于配置

什么是约定大于配置 "约定大于配置"&#xff08;Convention Over Configuration&#xff09;是一种理念&#xff0c;旨在通过默认约定和规则来减少开发人员需要做的配置工作。在Spring Boot框架中&#xff0c;这一原则得到了充分应用&#xff0c;帮助开发者更快地构…

300分钟吃透分布式缓存-15讲:如何深入理解、应用及扩展 Twemproxy?

Twemproxy 架构及应用 Twemproxy 是 Twitter 的一个开源架构&#xff0c;它是一个分片资源访问的代理组件。如下图所示&#xff0c;它可以封装资源池的分布及 hash 规则&#xff0c;解决后端部分节点异常后的探测和重连问题&#xff0c;让 client 访问尽可能简单&#xff0c;同…

AI时代,我们需要什么能力?

AI 时代&#xff0c;一定会重构很多行业&#xff0c;也会重构人民的生活工作方式&#xff0c;那么 AI 时代&#xff0c;我们需要培养什么能力呢&#xff1f; 我们应该去做那些 AI 做不了的事情&#xff01;让 AI 成为我们的工具&#xff0c;助力我们更高效的解决问题&#xff…

Java - 获取汉字大写首字母输出

背景 有个项目需要将一批字符串的拼音首字母输出并大写&#xff0c;写了个工具类。 实现 需要引入外部jar。 <dependency><groupId>com.belerweb</groupId><artifactId>pinyin4j</artifactId><version>2.5.1</version> </dep…

C++之set、multiset

1、set简介 set是一种关联式容器&#xff0c;包含的key值唯一&#xff0c;所有元素都会在插入时自动被排序&#xff0c;其存储结构为红黑树。set只能通过迭代器(iterator)访问。 set和multiset的区别&#xff1a; &#xff08;1&#xff09;set不允许容器中有重复的元素&…

VUE3中的组件传值

一、父传子(props) 在子组件中可以使用defineProps接收父组件向子组件的传值 父组件fatherPage.vue&#xff1a; <template><div class"father"><button click"a a 1">按钮</button><childPage :a"a" /><…

在Windows系统上安装Docker和SteamCMD容器的详细指南有哪些?

在Windows系统上安装Docker和SteamCMD容器的详细指南有哪些&#xff1f; 安装Docker&#xff1a; 首先&#xff0c;需要在Windows操作系统上激活WSL2功能。这是因为Docker作为一个容器工具&#xff0c;依赖于已存在并运行的Linux内核环境。可以通过使用winget来安装Docker。具体…

禁止u盘拷贝的方法,U盘文件防止拷贝的方法

某大型制造企业在研发一款新产品时&#xff0c;涉及到了大量的机密数据和设计图纸。为了方便工作&#xff0c;研发部门的员工经常使用U盘在不同电脑之间传输数据。 然而&#xff0c;由于缺乏对U盘的有效管理&#xff0c;导致了一起严重的数据泄露事件。 事件经过&#xff1a;…

IEEE 802.11a协议

IEEE 802.11 系列协议主要使用了 OFDM 调制技术&#xff0c;是现今局域无线网的通用标准&#xff0c;被广泛应用于 WIFI 通信中&#xff0c;WIFI 版本及其对应的 802.11 协议版本如下&#xff1a; Wi-Fi 1 是 1999 年发布的 802.11b 标准。Wi-Fi 2 是 802.11a 标准&#xff0c…

Vue3_2024_2天【Vue3组合式setup用法及响应式ref和reactive】

第一&#xff1a;浅谈 | 不可不知 1.vue3目录介绍&#xff08;区别Vue2没有的&#xff09; vue3&#xff0c;默认使用ts语言&#xff0c;但是ts一开始无法识别某些文件&#xff0c;这里是系统默认配置&#xff1b; 2.vue2中的入口文件是main.js&#xff0c;而vue3这里的入口文…

【CSS】CSS简介,CSS基础选择器详解

目录 css简介 css语法规范 css代码风格&#xff1a; css选择器的作用 css基础选择器 标签选择器 类选择器 类选择器---多类名 id选择器 id选择器和类选择器的区别&#xff1a; 通配符选择器 总结 ⭐css简介 CSS 是层叠样式表 ( Cascading Style Sheets ) 的简称,也…

二级医院云HIS系统,云HIS源码,支持分院HIS,集团HIS

云HIS具有可扩展、易共享、易协同、低成本、体验号、更便捷、易维护的优势&#xff0c;重新定义了数字化医院信息系统&#xff0c;实现数字化医院信息系统的转型升级。云 HIS 系统功能完善&#xff0c;涵盖临床各业务部门&#xff0c;采集、抽提、汇总、存贮、展现所有的临床诊…

【HTML】HTML基础系列文章小小总结,运用标签写出网页!

宇宙级声明&#xff01;这次只运用了一些基础标签&#xff0c;希望不要丑到大家~ 目录 效果预览&#xff1a;​编辑​编辑 点击百度百科 点击图片 点击下载 标签说明 源代码 效果预览&#xff1a; 点击百度百科 点击图片 点击下载 标签说明 标题 加粗文字 下划线 换行 分…

电商小程序10分类管理

目录 1 分类数据源2 搭建功能3 创建变量读取数据4 绑定数据总结 本篇我们介绍一下电商小程序的分类管理功能的开发&#xff0c;先看我们的原型图&#xff1a; 在首页我们是展示了四个分类的内容&#xff0c;采用上边是图标&#xff0c;下边是文字的形式。使用低代码开发&#…

Docker实战——网络通信

目录 一、Docker 容器网络通信的基本原理1、查看 Docker 容器网络&#xff08;1&#xff09;新建一个 Dockerfile文件&#xff0c;内容如下&#xff1a;&#xff08;2&#xff09;使用以下命令创建镜像&#xff08;3&#xff09;基于 debian 的镜像创建一个容器&#xff0c;并进…

每日一类:QLabel深入解析

QLabel是Qt中用于显示文本或图像的控件&#xff0c;属于Qt Widgets模块。它是展示静态内容的理想选择&#xff0c;支持富文本格式&#xff0c;使得文本可以包含不同的字体、颜色和链接。QLabel也可以用来显示图像&#xff0c;包括动态图像。此外&#xff0c;它还支持文本和图像…

源码解析篇 | YOLOv8官方源码项目目录结构解析

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。YOLOv8是一种目标检测算法&#xff0c;它是YOLO&#xff08;You Only Look Once&#xff09;系列算法的第8个版本。YOLOv8相比于之前的版本&#xff0c;在检测精度和速度上都有所提升&#xff0c;它在各种场景下都表现出色…

Acwing 每日一题 空调 差分 贪心

&#x1f468;‍&#x1f3eb; 空调 &#x1f468;‍&#x1f3eb; 参考题解 import java.util.Scanner;public class Main {static int N (int) 1e5 10;static int[] a new int[N];static int n;public static void main(String[] args){Scanner sc new Scanner(System.…