C++ 11 实现定时器

用C++写了个定时器。

项目的需求是原来Windows的程序,用到了windows APi的 SetTimerKillTimer 来创建和销毁定时器,现在要移植代码到Linux,实现与其相似的功能。

首先创建一个Timer类,管理单个定时器。

 1 typedef std::function<void()> TimerFunc;
 2 
 3 #define TIMER_ID unsigned long
 4 #define INTERVAL unsigned int
 5 
 6 class MyTimer{
 7 public:
 8     MyTimer(TIMER_ID _id, INTERVAL _interval, TimerFunc _func);
 9     void stopTimer();
10     void startTimer();
11     ~MyTimer();
12 private:
13     TIMER_ID m_id;
14     INTERVAL m_interval;
15     bool m_stop;
16     TimerFunc m_func;
17     std::future<int> m_future;
18 };

用一个全局hash表来管理Timer,并定义一个全局的mutex实现线程锁

1 std::unordered_map<TIMER_ID, MyTimer*> TimerMap;
2 std::mutex g_mutex;

定义一个TimerServer类实现接口:

 1 class TimerService
 2 {
 3 public:
 4     static TIMER_ID setTimer(INTERVAL _interval, TimerFunc _func);
 5     static void killTimer(TIMER_ID _id);
 6 };
 7 
 8 static TIMER_ID NewTimerID = 0;
 9 
10 TIMER_ID TimerService::setTimer(INTERVAL _interval, TimerFunc _func){
11     MyTimer* pTimer = new MyTimer(NewTimerID, _interval, _func);
12     TimerMap[NewTimerID] = pTimer;
13     pTimer->startTimer();
14     return NewTimerID++;
15 }
16 
17 void TimerService::killTimer(unsigned long _id)
18 {
19     MyTimer* pTimer = TimerMap.at(_id);
20     if (pTimer){
21         pTimer->stopTimer();
22         delete pTimer;
23         TimerMap.erase(_id);
24     }
25 }

Timer内部的方法实现:

 1 MyTimer::MyTimer(unsigned long _id, unsigned int _interval, TimerFunc _func)
 2 {
 3     m_id = _id;
 4     m_interval = _interval;
 5     m_func = _func;
 6     m_stop = false;
 7 }
 8 
 9 void MyTimer::startTimer()
10 {
11     m_future = std::async(std::launch::async, [this](){
12         while(true){
13             if(m_stop)
14                 break;
15             std::this_thread::sleep_for(std::chrono::milliseconds(m_interval));
16             std::lock_guard<std::mutex> lock(g_mutex);
17             m_func();
18         }
19         return 0;
20     });
21 }
22 
23 void MyTimer::stopTimer()
24 {
25     m_stop = true;
26     m_future.wait();
27 }
28 
29 MyTimer::~MyTimer()
30 {
31 
32 }

测试:

 1 #include <iostream>
 2 #include "mytimer.h"
 3 #include <chrono>
 4 #include <functional>
 5 
 6 using namespace std;
 7 
 8 void printWorld() {
 9     cout << "world" << endl;
10 }
11 
12 class Router{
13 public:
14     void countSelf() {
15         cout << "Count is " << count << endl;
16         count++;
17     }
18 
19     Router(){
20         count = 0;
21         id = TimerService::setTimer(1000, std::bind(&Router::countSelf, this));
22     }
23     ~Router() {
24         TimerService::killTimer(id);
25     }
26 
27 private:
28     unsigned int count;
29     unsigned long id;
30 };
31 
32 int main()
33 {
34     auto l1 = TimerService::setTimer(1000, [](){cout << "hello" << endl;});
35     auto l2 = TimerService::setTimer(1000, std::bind(printWorld));
36     Router *r = new Router;
37 
38     std::this_thread::sleep_for(std::chrono::seconds(3));
39     TimerService::killTimer(l2);
40     delete r;
41     std::this_thread::sleep_for(std::chrono::seconds(5));
42     return 0;
43 }

Github

 

上一篇:2021-09-18


下一篇:Use of @OneToMany or @ManyToMany targeting an unmapped class