My E-mail 用志趣吸引人;用感情留住人;用技術武裝人;用創新發展人;一切以人為本!

Leo LU

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 &current_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方式

 

关注下一篇《精确定时器》

posted on 2010-02-10 01:00 Leo LU 阅读(...) 评论(...) 编辑 收藏

导航

统计信息