ACE Timer依赖OS时间的解决办法

 ACE默认的时钟实现依赖操作系统时钟(ACE_OS::gettimeofday),例如改小系统时间会造成时钟触发延时。该问题可通过修改timer_queue的gettimeofday函数来解决。


网上提及的一种办法是使用ACE_High_Res_Timer::gettimeofday_hr替换ACE_OS::gettimeofday,测试发现该方法在Windows XP上可用,在SUSE10上仍然不行;跟踪发现SUSE10上ACE_High_Res_Timer::gettimeofday_hr调用了::clock_gettime(),clockid为CLOCK_REALTIME——这样仍然会依赖OS时间。使用CLOCK_MONOTONIC调用::clock_gettime(),可得到不依赖OS时间的值,而这需要增加ACE的编译宏ACE_HAS_CLOCK_GETTIME_MONOTONIC(可以在config.h中增加定义)

另一个方法是自己实现一个替代函数,下面的getTime是一个例子:

#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include "ace/Timer_Queue_Adapters.h"
#include "ace/Event_Handler.h"
#include "ace/Timer_Wheel.h"
#include "ace/reactor.h"
#include "ace/High_Res_Timer.h"


using namespace std;


ACE_Thread_Timer_Queue_Adapter<ACE_Timer_Wheel> active_timer_ ;


class CHandler: public ACE_Event_Handler
{
public:
    virtual int handle_timeout (const ACE_Time_Value &current_time, const void *act)
    {
        cout<< "time out "<< endl;
        return 0;
    }
};


ACE_Time_Value getTime()
{
  ifstream f("/proc/uptime");
  string str; 
  f >> str;
  
  string substr = str.substr(0, str.find("."));
  string substr1 = str.substr(str.find(".")+1, 2);
  int i = atoi(substr.c_str());
  cout<<substr<<" "<<substr1<<endl;
  return ACE_Time_Value(i, atoi(substr1.c_str())*10*1000);
}


void startTimer()
{
    static CHandler hdl;


    active_timer_.timer_queue()->gettimeofday(getTime);
    const ACE_Time_Value curr_tv = getTime();


    //active_timer_.timer_queue()->gettimeofday(ACE_High_Res_Timer::gettimeofday_hr);
    //const ACE_Time_Value curr_tv = ACE_High_Res_Timer::gettimeofday_hr();
    long timerID = active_timer_.schedule(&hdl, 0, curr_tv + ACE_Time_Value(1), ACE_Time_Value(1));
    if(timerID < 0)
    {
        cout<<"schedule time failed"<<endl;
    }
    active_timer_.activate();
}


int main()
{
    //ACE_High_Res_Timer::global_scale_factor();
    startTimer();
    for(;;)
    {
         sleep(7);
    }
}

你可能感兴趣的:(thread,windows,timer,String,OS,SuSE)