博客 / 詳情

返回

【C++】實現一個定時器

前言

實現一個週期性調用類。通過TaskTimer構造函數設置週期,通過setTimerFun傳入要調用函數和參數,start啓動,stop停止。比如要每30秒發送一個心跳包可以把發送包的函數傳入定時器,定時器會創建一個線程週期性發送這個包。

實現

TaskTimer主要有開始、停止、設置調用函數與參數,三個方法。

  • TaskTimer.h
  1 #ifndef  _TASKTIMER_H
  2 #define _TASKTIMER_H
  3 //計時器 實現循環註冊
  4 #include <iostream>
  5 #include <thread>
  6 #include <chrono>
  7 #include <unistd.h> 
  8 
  9 //定時器調用的函數
 10 typedef void(*timerFunCallBack)(void * param);
 11 
 12 class  TaskTimer{
 13 
 14     public:
 15         TaskTimer(unsigned long second);
 16         ~TaskTimer();
 17 
 18         void start();
 19         void stop();
 20 
 21         void setTimerFun(timerFunCallBack fun,void* param);
 22         static void * timer(void * context);
 23 
 24     private:
 25         //回調函數
 26         timerFunCallBack m_timerFun;
 27         //回調函數參數
 28         void * m_funParam;
 29         //間隔
 30         unsigned long m_timeSecond;
 31         bool m_isStop;
 32         std::thread m_thread;
 33 };
 34 
 35 #endif

  • TaskTimer.cpp
 1 #include "TaskTimer.h"
  2 #include <sys/time.h>
  3 
  4 TaskTimer::TaskTimer(unsigned long second):m_timeSecond(second),m_isStop(true){
  5         m_timerFun = nullptr;
  6         m_funParam = nullptr;
  7 		
  8 }
  9 TaskTimer:: ~TaskTimer(){
 10     stop();
 11 }
 12 
 13 void TaskTimer::start(){
 14     //創建線程
 15     m_isStop = false;
 16     m_thread = std::thread(&TaskTimer::timer,(void*)this);
 17     std::cout<<"thread create"<<std::endl;
 18 }
 19 void TaskTimer::stop(){
 20     m_isStop = true;
 21     if(m_thread.joinable()){
 22         m_thread.join();
 23     }
 24 }
 25 
 26  void TaskTimer::setTimerFun(timerFunCallBack fun,void* param){
 27     m_timerFun = fun;
 28     m_funParam = param;
 29 }
 30 
 31 void * TaskTimer::timer(void * taskTimer){
 32     std::cout << "Timer thread function ENTERED!" << std::endl;
 33     TaskTimer * pthis = (TaskTimer * )taskTimer;
 34     if(nullptr  == pthis){
 35         return nullptr;
 36     }
 37     unsigned long curTime = 0;//當前時間
 38     unsigned long lastTime = 0;//上次更新時間時間
 39     struct  timeval current;
 40     while(!pthis->m_isStop){
 41         gettimeofday(&current,nullptr);
 42         //換算成毫秒 tv_sec 秒 tv_usec 微妙
 43         curTime = current.tv_sec+current.tv_usec/1000000;
 44 
 45          // 處理時間回退情況
 46          if (curTime < lastTime) {
 47                  lastTime = curTime;
 48                  continue;
 49         }
 50 
 51         if((curTime-lastTime) >= (pthis->m_timeSecond)){
 52             lastTime = curTime;
 53             if(pthis->m_timerFun != nullptr){
 54                 pthis->m_timerFun(pthis->m_funParam);
 55             }
 56         }else{
 57                 usleep(1000*1000);
 58                 continue;
 59         }
 60     }
 61     return nullptr;
 62 }

  • main.cpp

main函數實現調用。

  1 #include <iostream>
  2 #include <string>
  3 #include "TaskTimer.h"
  4 
  5 static void func(void*param){
  6         int * pi = (int*)param;
  7         std::cout<<"hello !"<< *pi << std::endl;
  8 }
  9 
 10 int main(){
 11 
 12         //TaskTimer* timer = new TaskTimer(3);
 13         TaskTimer timer(1);
 14         int  param  = 123;
 15         int * ptr = &param;
 16         timer.setTimerFun(func,(void *)ptr);
 17         timer.start();
 18 
 19         usleep(10000*1000);
 20         timer.stop();
 21         return 0;
 22 }

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.