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


    前言:

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

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

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

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

    1.windows api定时器

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

    SetTimer函数和KillTimer函数

    1. /*
    2. * Windows Functions
    3. */
    4. WINUSERAPI
    5. UINT_PTR
    6. WINAPI
    7. SetTimer(
    8. _In_opt_ HWND hWnd, //窗口句柄
    9. _In_ UINT_PTR nIDEvent,//注册的对应任务的ID,
    10. _In_ UINT uElapse, //设置的每次执行该回调函数的时间间隔,单位是毫秒
    11. _In_opt_ TIMERPROC lpTimerFunc); //注册的对应任务的回调函数,

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

    1. WINUSERAPI
    2. BOOL
    3. WINAPI
    4. KillTimer(
    5. _In_opt_ HWND hWnd, // 窗口句柄
    6. _In_ UINT_PTR uIDEvent); //对应的定时任务的id

    来一个实际的Demo:

    1. #include
    2. #include
    3. using namespace std;
    4. void CALLBACK Task1(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
    5. {
    6. cout << "task1" << endl;
    7. }
    8. void CALLBACK Task2(HWND hWnd, UINT nMsg, UINT nTimerid, DWORD dwTime)
    9. {
    10. cout << "task2" << endl;
    11. }
    12. void main()
    13. {
    14. MSG msg;
    15. SetTimer(NULL, 111, 1000, (TIMERPROC)Task1);
    16. SetTimer(NULL, 112, 1000, (TIMERPROC)Task2);
    17. //消息死循环,一直监听键盘的输入,然后把消息发送到主程序窗口
    18. //我们按下ctrl + c的时候,程序会自动停止
    19. while (GetMessage(&msg, NULL, NULL, NULL))
    20. {
    21. if (msg.message == WM_TIMER)
    22. {
    23. TranslateMessage(&msg); //把键盘字符,转换成协议消息
    24. DispatchMessage(&msg);//把消息命令发送到主窗口
    25. }
    26. }
    27. KillTimer(NULL, 111);
    28. KillTimer(NULL, 112);
    29. }

    输出打印结果:

    过程说明:

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

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

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

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

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

    有两种定时器:

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

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

    task_timer.h

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. class TaskTimer {
    7. public:
    8. TaskTimer() {};
    9. ~TaskTimer() {};
    10. private:
    11. void ThreadInterval(int interval, std::function<void()> task)
    12. {
    13. while (!stop_sign)
    14. {
    15. task();
    16. std::chrono::milliseconds dura(interval); //间隔几秒
    17. std::this_thread::sleep_for(dura);
    18. }
    19. }
    20. void ThreadFixedTime(struct tm time_data, std::function<void()> task)
    21. {
    22. time_t t = time(nullptr);
    23. struct tm nowTime;
    24. while (!stop_sign)
    25. {
    26. t = time(nullptr);
    27. localtime_s(&nowTime, &t);
    28. //std::cout << nowTime.tm_hour << " " << nowTime.tm_min << " " << nowTime.tm_sec << " " << std::endl;
    29. if (time_data.tm_hour == nowTime.tm_hour && time_data.tm_min == nowTime.tm_min && time_data.tm_sec == nowTime.tm_sec)
    30. {
    31. task();
    32. }
    33. std::chrono::milliseconds dura(900);
    34. std::this_thread::sleep_for(dura);
    35. }
    36. }
    37. public:
    38. //添加一个任务间隔一段时间执行一次
    39. void AddTaskInterval(int interval, std::function<void()> task)
    40. {
    41. std::thread( &TaskTimer::ThreadInterval, this, interval, task).detach();
    42. }
    43. //添加一个任务,在每天的固定时间执行
    44. void AddTaskFixedTime(struct tm time_data, std::function<void()> task)
    45. {
    46. std::thread(&TaskTimer::ThreadFixedTime, this, time_data, task).detach();
    47. }
    48. //停止定时器
    49. void StopTaskInterval()
    50. {
    51. stop_sign = true;
    52. }
    53. private:
    54. std::atomic<bool> stop_sign = false;
    55. };

    main.cpp

    1. #include
    2. #include "task_timer.h"
    3. void func1()
    4. {
    5. std::cout << "func1\n" << std::endl;
    6. }
    7. void func2()
    8. {
    9. std::cout << "func2\n" << std::endl;
    10. }
    11. int main(int argc, char* argv[])
    12. {
    13. TaskTimer timer;
    14. //timer.AddTaskInterval(1000, func1);
    15. //timer.AddTaskInterval(1000, func2);
    16. struct tm time_data;
    17. time_data.tm_hour = 17;
    18. time_data.tm_min = 14;
    19. time_data.tm_sec = 58;
    20. timer.AddTaskFixedTime(time_data, func1);
    21. timer.AddTaskFixedTime(time_data, func2);
    22. getchar();
    23. return 0;
    24. }

  • 相关阅读:
    用户登录功能
    【C++】AVL树
    Hibernate 分页
    MatrixOne 实战系列回顾 | 建模与多租户
    ClickHouse distributed表引擎
    布隆过滤器
    【ubuntu 搜狗输入法】ubuntu下搜狗输入法不能打印中文的所有问题都这样解决!
    Vue3封装自定义指令和hooks,并发布npm包
    Mysql中的目录和文件详解
    Java - HashMap原理分析
  • 原文地址:https://blog.csdn.net/dz131lsq/article/details/136351113