用C++写了个定时器。
项目的需求是原来Windows的程序,用到了windows APi的 SetTimer 和 KillTimer 来创建和销毁定时器,现在要移植代码到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 }
Edit:
代码做了一些优化,去掉TimerService类,用static替代全局变量
MyTimer.h
1 #ifndef MYTIMER_H
2 #define MYTIMER_H
3
4 #include <functional>
5 #include <atomic>
6 #include <future>
7 #include <list>
8 #include <map>
9
10 typedef std::function<void()> TimerFunc;
11
12 #define TIMER_ID unsigned long
13 #define INTERVAL unsigned int
14 #define ERRCOUNT unsigned char
15
16 class MyTimer{
17 public:
18 MyTimer(TimerFunc _func);
19
20 static MyTimer* GetInstance(TimerFunc _func);
21 void stopTimer();
22 void startTimer(INTERVAL _interval);
23 void setTimerEnabled(bool _enabled);
24 ~MyTimer();
25
26 private:
27 TIMER_ID m_id;
28 INTERVAL m_interval;
29 bool m_stop;
30 bool m_enabled;
31 TimerFunc m_func;
32 std::future<int> m_future;
33
34 static std::map<TIMER_ID, MyTimer*> s_timerMap;
35 static std::mutex s_mutex;
36 static TIMER_ID s_id;
37
38 };
39
40 #endif // MYTIMER_H
MyTimer.cpp
1 #include "mytimer.h"
2 #include <chrono>
3 #include <thread>
4 #include <utility>
5 #include <functional>
6
7 std::map<TIMER_ID, MyTimer*> MyTimer::s_timerMap;
8 std::mutex MyTimer::s_mutex;
9 TIMER_ID MyTimer::s_id = 0;
10
11 MyTimer::MyTimer(TimerFunc _func)
12 {
13 m_id = s_id;
14 m_interval = 0;
15 m_func = _func;
16 m_stop = false;
17 m_enabled = false;
18 s_timerMap[m_id] = this;
19 }
20
21 MyTimer *MyTimer::GetInstance(TimerFunc _func)
22 {
23 return new MyTimer(_func);
24 }
25
26 void MyTimer::startTimer(INTERVAL _interval)
27 {
28 m_interval = _interval;
29 m_enabled = true;
30 m_future = std::async(std::launch::async, [this](){
31 while(true){
32 if(m_stop)
33 break;
34 std::this_thread::sleep_for(std::chrono::milliseconds(m_interval));
35 std::lock_guard<std::mutex> lock(s_mutex);
36 if(m_enabled && !m_stop)
37 m_func();
38 }
39 return 0;
40 });
41 }
42
43 void MyTimer::setTimerEnabled(bool _enabled)
44 {
45 46 m_enabled = _enabled;
47 }
48
49 void MyTimer::stopTimer()
50 {
51 m_stop = true;
52 m_future.wait();
53 }
54
55 MyTimer::~MyTimer()
56 {
57 if (m_stop == false)
58 stopTimer();
59 if (s_timerMap.find(m_id) != s_timerMap.end())
60 s_timerMap.erase(m_id);
61 }
测试:
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 pTimer = MyTimer::GetInstance(std::bind(&Router::countSelf, this));
22 pTimer->startTimer(500);
23 }
24 ~Router() {
25 pTimer->stopTimer();
26 }
27
28 private:
29 unsigned int count;
30 MyTimer* pTimer;
31 };
32
33 int main()
34 {
35 MyTimer* pTimer1;
36 MyTimer* pTimer2;
37 pTimer1 = MyTimer::GetInstance([](){cout << "hello" << endl;});
38 pTimer2 = MyTimer::GetInstance(std::bind(printWorld));
39 pTimer1->startTimer(1000);
40 pTimer2->startTimer(1000);
41 Router *r = new Router;
42 std::this_thread::sleep_for(std::chrono::seconds(2));
43 pTimer2->setTimerEnabled(false);
44 std::this_thread::sleep_for(std::chrono::seconds(3));
45 pTimer2->setTimerEnabled(true);
46 delete pTimer1;
47 delete r;
48 std::this_thread::sleep_for(std::chrono::seconds(5));
49 return 0;
50 }
原文链接: https://www.cnblogs.com/Asp1rant/p/14881089.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/211367
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!