ACE定时器与windows自带的定时器
这段时间将之前的工程都转换到了eclipse+CDT+vc的环境下开发了,感觉比用vc要好的多,开发速度也要快得多,不过唯一的麻烦是写Makefile太过麻烦,看看是不是能将auto-tools工具导过来!
以上是废话了,有兴趣的朋友可以一起交流下。
定时器,是os固有的特性,每个os实现方式都不同,下面就windows下自带的和ace下实现的定期器做个比较:
基本应用定时器:
定时器测试代码如下:
->基于消息队列的:
int main(int argv,char* argc[]){ WndTimer timer; timer.setHandler(handler); timer.init(NULL,10); timer.run(); // WndTimer timer2; // timer2.setHandler(handler); // timer2.init(NULL,700); // timer2.run(); MSG msg; while (GetMessage(&msg, NULL, 0,0) ) { DispatchMessage(&msg); } return 0; }
->基于ACE的:
int main(int argv,char* argc[]){ ACE::init(); wjtimer *timer = new wjtimer; ACE_Time_Value tv(0,10),tv2(0,10); ACE_Reactor::instance()->schedule_timer(timer,(const int*)44,tv,tv2); while(1) ACE_Reactor::instance()->handle_events(); return 0; }
windows封装后的定时器如下:
/* * WndTimer.h * * Created on: 2010-2-8 * Author: Administrator */ #ifndef WNDTIMER_H_ #define WNDTIMER_H_ #include <WINDOWS.H> #include <iostream> #include <string> #include <map> namespace UD { typedef void (*HANDLERFUN)(LPARAM lParam); const int TIMER_RUN_FAILED = 0; const int TIMER_RUN_COMPLETE = -1;//未用 class WndTimer { UINT _uElapse; LPARAM _param; HWND _wnd; HANDLERFUN _handler; DWORD _timerID; std::string _szMessage; static std::map<DWORD,WndTimer*> s_mapTimers; void appendErrorMsg(){ LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); _szMessage+="Error:"; _szMessage+=(LPCTSTR)lpMsgBuf; _szMessage+="\r\n"; LocalFree( lpMsgBuf ); } static VOID WINAPI TimerProc(HWND hwnd, // handle to window UINT uMsg, // WM_TIMER message unsigned int idEvent, // timer identifier DWORD dwTime // current system time ){ WndTimer *currentTimer = s_mapTimers[idEvent]; if (currentTimer->_handler != NULL) { currentTimer->_handler(currentTimer->_param); } } public: WndTimer() { init(NULL,0); } WndTimer(HWND wnd, DWORD uElapse, HANDLERFUN handler) { init(wnd, uElapse); setHandler(handler); } virtual ~WndTimer(){ if(_timerID!=TIMER_RUN_FAILED) terminate(); } void run() { _timerID = SetTimer(_wnd, _timerID, _uElapse, &TimerProc); if(_timerID == TIMER_RUN_FAILED){ appendErrorMsg(); }else{ s_mapTimers.insert(std::make_pair(_timerID,this)); } } void terminate() { if(_timerID == TIMER_RUN_FAILED) return; KillTimer(_wnd, _timerID); s_mapTimers.erase(_timerID); _timerID = TIMER_RUN_FAILED; } void init(HWND wnd, UINT uElapse,LPARAM param = 0,DWORD timerID = 0) { if(wnd!=NULL&&timerID!=-1) _timerID = timerID; else _timerID = TIMER_RUN_FAILED; _wnd = wnd; _uElapse = uElapse; if(param == 0) _param = (LPARAM)(&_timerID); else _param = param; } void setHandler(HANDLERFUN handler) { _handler = handler; } const char* getMessage(){ return _szMessage.c_str(); } }; } #endif /* WNDTIMER_H_ */
/* * WndTimer.cpp * * Created on: 2010-2-8 * Author: Administrator */ #include "WndTimer.h" namespace UD { std::map<DWORD,WndTimer*> WndTimer::s_mapTimers; }
ACE实现:
class wjtimer : public ACE_Event_Handler { public: virtual int handle_timeout(const ACE_Time_Value ¤t_time, const void *act /**//* = 0 */){ const int *num = ACE_static_cast(const int*,act); ACE_DEBUG((LM_DEBUG, ACE_TEXT("%d "),num)); return 0; } protected: private: };
同样运行一分钟(10ms执行一次):
windows方式:3831次
ACE:3900次
基本相同,但CPU使用前者基本为0,后者为50%左右
将执行频率调到1,3,5ms基本都在4000左右,两个实现方式,精确度都只有10ms
推荐使用windows方式