用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 }