• 浅尝boost之timer



          我一直是在努力推介boost,因为boost是一块美玉,但,没有什么是完美的。现在,我将暴露出boost的一点瑕疵:boost::timer。虽说是瑕不掩瑜,但瑕疵就是瑕疵。先看一看下面的例子:

     // win2000 中vc7.1编译运行
     boost::timer t;
     Sleep(
    1000);
     cout 
    << t.elapsed() << endl;
     
     
    // redhat9 中gcc3.2.3编译运行
     boost::timer t;
     sleep(
    1);
     cout 
    << t.elapsed() << endl;


     
         他们的结果是一样吗?不同的操作系统,时钟精度是不一样,结果自然不完全一样;但我说的不一样不是这一点小小的差异,而是在redhat9上t.elapsed()返回的竟然是 0 。boost::progress_timer也有同样问题,为什么 ?
     
         boost::timer是一个clock()的非常简单的封装,简单到我不认为有理由存在于boost之样的库之中。基本只是下面的东西

     class timer
     
    {
      
    public:
              timer()  
    { _start_time = clock(); } 
       
    void   restart()  { _start_time = clock(); } 
       
    double elapsed() constreturn  double(clock() - _start_time) / CLOCKS_PER_SEC; }
      
    private:
        clock_t _start_time;
     }
    // timer
     


         所以抛开boost::timer这层包装来看,就是clock与sleep之间的问题了。为什么不用sleep就可以得到流逝的时间呢(cin.get()也不能得到)。推其原因在于linux平台上sleep时,clock是获得CPU被使用的时间。而这时进程会等待一个signal,这一段时间CPU不会被使用,clcok()认为时间没有流逝所致。而windows平台却是认为Sleep时也是有时间流逝的,而不是看CPU有没有被使用,我也是这么考虑的 :-)。这样一来两者之间就有了极大的不同。
     
         所以,想要一个正确的跨平台的timer就得自己动些手了。 
         一种方案是修改sleep,但问题是要保证调用者准确的调用了这个函数,另外,这个方法使用了轮询,感觉不好。一般sleep的调用者都会希望这时候程序不占用CPU资源。
     void sleep( clock_t wait )
     {
        clock_t goal;
        wait = (clock_t) wait * CLOCKS_PER_SEC;
        goal = wait + clock();
        while( goal > clock());
     }
     
         另一种方案是自己取当前时间,取代clock(),至于用什么函数则看自己的要求了。发现在这个问题是在一个ACE程序中,我就用ACE封装的函数包装了一个,不同平台的sleep也可用ACE_OS::sleep代替
     

     class Elapsed
     
    {
     
    public:
      Elapsed()
      
    {
       restart();
      }

      
    void restart()
      
    {
       _tv 
    = ACE_OS::gettimeofday();
      }

      
    // 返回以秒为单位的流逝时间
      long elapsed()
      
    {
       ACE_Time_Value now 
    = ACE_OS::gettimeofday();
       
    return now.sec() - _tv.sec();
      }

      
      ACE_Time_Value ACE_elapsed()
      
    {
       
    return (ACE_OS::gettimeofday() - _tv);
      }

      
     
    private:
      ACE_Time_Value _tv;
     }
    ;


      
         如果没有用ACE,完成一个这样的封装也是很简单的,因为,这个功能实在简单:-)

  • 相关阅读:
    Java正则表达式
    Java 字符串处理
    Number 和 Math 类
    Day05:集合操作——线性表(二) / 查找表 / 文件操作——File(一)
    Android IPC(进程间通信)Binder机制
    Android Service服务源码相关分析
    Android系统修改相关收集
    常用
    JAVA设计模式
    【转载】Reactor模式和NIO
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1934808.html
Copyright © 2020-2023  润新知