前言:
當我有一個開發需求,符合下面的條件
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;
}