前言:
当我有一个开发需求,符合下面的条件
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;
}