Boost源码简析系列——timer(2)

原创 2004年03月20日 14:37:00

Boost源码简析系列——timer2

对于timer的第二个头文件中包含的两个类,我早就想写出来,但是最近忙着写代码,今天终于有时间写了,并且前段时间解决了一个问题,用的就是timer,所以也给了我动力。

剩下的两个类,grogress_timergrogress_display都定义在头文件progress.hpp中,由Beman Dawes编写,最新版是2001111日发表。

1.         progress_timer

#ifndef BOOST_PROGRESS_HPP

#define BOOST_PROGRESS_HPP

#endif

同样,这是几乎每个头文件都会有的包含保护符。

#include <boost/timer.hpp>    //因为progress_timer继承于类timer,所以包含进来。

#include <boost/utility.hpp>        //timer定义中也遇到,其中包含了类noncopyable的定义,当progress_timer继承了这个类后,就没有了拷贝构造函数了。

#include <boost/cstdint.hpp>      //boost在这里面定义了很多数据类型。

#include <iostream>

#include <string>                      //这两个没有什么好说的,但是现在写代码最好还是以标准库为准,比如用string,而不是用char *

class progress_timer : public timer, private noncopyable

{

 public:

  explicit progress_timer( std::ostream & os = std::cout )

     : m_os(os) {}

  ~progress_timer()

  {

    try

    {

      std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,

std::istream::floatfield );

      std::streamsize old_prec = m_os.precision( 2 );

      m_os << elapsed() << " s/n" << std::endl;

      m_os.flags( old_flags );

      m_os.precision( old_prec );

    }

    catch (...) {}

  }

 private:

  std::ostream & m_os;

};

从代码上看,progress_timer真是简单的可以了,她继承于timernoncopyable。主要代码都在析构函数中,意思就是说在其对象析构的时候把,对象生存的时间显示出来。

构造函数用explicit表示不能用于隐藏类型转换。

计算流逝的时间的函数是elapsed,是从timer继承而来。要读懂这段东西,我想最复杂就是对输出流的操作了,这里涉及到了,对输出流输出格式状态的设置,对输出流输出精度的设置。

fmtflags:是一种在标准库流中定义的一种数据类型,她的对象表示了流的i/o操作的一组标志和整数值控制。这些标志有很多,比如:

boolalpha

用符号形式表示真假。

dec

10为基数输出

hex

16为基数输出

fixed

点数输出格式

showbase

输出前缀,八进制为0,十六进制为0x

floatfield

与浮点数输出有关的标志组

unitbuf

每次输出操作之后刷新

在这里只是列出了极少的一部分,比较详细的描述可参考The C++ Programming Language 21章。

std::istream::fmtflags old_flags = m_os.setf( std::istream::fixed,

std::istream::floatfield );

所以这条语句的意思就是说,给标准输出对象m_os设置输出格式是浮点数格式,并保存原来的格式,便于完成输出后恢复设置。

std::streamsize old_prec = m_os.precision( 2 );

这条设置了,输出精度为2

剩下的工作就是输出,并恢复了。

在这段代码中用了异常处理技术。

try

{

//…

}

catch(…){//…}

在这里用catch后面的表示捕捉所有的异常。

2 grogress_display

这个类好像与前面两个类没有一点关系,我们通过她可以在控制台程序中实现用一个进度条显示出我们任务的进展情况。

我们建造一个该类的对象时,会显示出一个进度条标尺,在调用operator ++函数时,决定是否增长进度条,直到到达标尺的最后停止。

class progress_display : private noncopyable

{

 public:

  explicit progress_display( unsigned long expected_count,

                             std::ostream & os = std::cout,

                             const std::string & s1 = "/n", //leading strings

                             const std::string & s2 = "",

                             const std::string & s3 = "" )

   : m_os(os), m_s1(s1), m_s2(s2), m_s3(s3) { restart(expected_count); }

 

  void restart( unsigned long expected_count )

  {

    _count = _next_tic_count = _tic = 0;

    _expected_count = expected_count;

 

m_os << m_s1 << "0%   10   20   30   40   50   60   70   80   90   100%/n"

     << m_s2 << "|----|----|----|----|----|----|----|----|----|----|"

     << std::endl  // endl implies flush, which ensures display

     << m_s3;

    if ( !_expected_count ) _expected_count = 1;

  }

unsigned long  operator+=( unsigned long increment )

  {

    if ( (_count += increment) >= _next_tic_count ) { display_tic(); }

    return _count;

  }

  unsigned long  operator++()           { return operator+=( 1 ); }

  unsigned long  count() const          { return _count; }

  unsigned long  expected_count() const { return _expected_count; }

  private:

  std::ostream &     m_os; 

  const std::string  m_s1; 

  const std::string  m_s2;

  const std::string  m_s3;

  unsigned long _count, _expected_count, _next_tic_count;

  unsigned int  _tic;

  void display_tic()

  {

    unsigned int tics_needed =

      static_cast<unsigned int>(

        (static_cast<double>(_count)/_expected_count)*50.0 );

    do { m_os << '*' << std::flush; } while ( ++_tic < tics_needed );

    _next_tic_count =

      static_cast<unsigned long>((_tic/50.0)*_expected_count);

    if ( _count == _expected_count ) {

      if ( _tic < 51 ) m_os << '*';

      m_os << std::endl;

      }

  }

};

这个类代码也比较简单,有几个data member需要说明一下:

_count

标定现在计数到什么位置。

_expected_count

标定计数可以到达的最大数。

_next_tic_count

下个要打进度标志的计数位置。

创建对象的时候,调用restart函数,显示出标尺,标尺用m_s1,m_s2,m_s3标定标尺的显示规格。

然后,每次进度条需要增加的时候调用menber functionoperator+=(),在这个函数中,_count += increment) >= _next_tic_count,增加_count,看是否到达下一个需要对进度条增加的位置,如果是,调用menber functiondisplay_tic()

而这个类理解的最困难的地方就在于display_tic(),这个函数做了几件事,首先是显示这次调用函数时,应该显示的进度条,计算出下次进度条增加的位置,当进度条也就是_count的计数到达最大值的时候,判断是否打最后一个进度条上的点。

在我们使用这个类的时候,需要的就是创建个对象,在该增加进度条的时候调用operator++()就行了。用起来也比较方便。

 

【Boost】boost库中timer定时器

同步Timer asio中提供的timer名为deadline_timer,它提供了超时计时的功能。首先以一个最简单的同步Timer为例来演示如何使用它。     #include      ...
  • liujiayu2
  • liujiayu2
  • 2015年12月23日 09:41
  • 2446

Boost.Asio学习之简单的HTTP服务器

Boost.asio实现简单的HTTP服务器
  • zhangxiao93
  • zhangxiao93
  • 2017年01月13日 10:29
  • 3080

Boost.deadline_timer实现定时器功能时需注意的时区问题

利用boost.deadline_timer() 可以很方便的实现定时器功能,详情参考:http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio...
  • Enter_
  • Enter_
  • 2015年04月11日 17:02
  • 2235

Timer 定时器(一)

说来惭愧,做Android开发一年多居然都不知道定时器为何物,直到最近项目中用到轮询查看底层源码才知道使用的是定时器,所以就趁着这个机会梳理下定时器的内部源码。 A facility for th...
  • LosingCarryJie
  • LosingCarryJie
  • 2017年12月21日 00:09
  • 27

ffmpeg源码简析(五)编码——avformat_alloc_output_context2(),avcodec_encode_video2()

1.avformat_alloc_output_context2()在基于FFmpeg的视音频编码器程序中,该函数通常是第一个调用的函数(除了组件注册函数av_register_all())。avfo...
  • King1425
  • King1425
  • 2017年04月24日 19:22
  • 558

boost 库 timer组件的源码分析 [大三四八九月实习]

体会一下能够列入C++准标准库的源代码设计思想。   一、源码 timer是学到的boost库的第一个组件,其被封装的源代码还是比较简单的,类摘要如下: class timer { pub...
  • misskissC
  • misskissC
  • 2013年08月08日 10:33
  • 915

ffmpeg源码简析(四)avcodec_find_encoder(),avcodec_open2(),avcodec_close()

avcodec_find_encoder()和avcodec_find_decoder()avcodec_find_encoder()用于查找FFmpeg的编码器,avcodec_find_decod...
  • King1425
  • King1425
  • 2017年04月24日 17:28
  • 557

uboot 源码分析(2)uboot 环境变量实现简析

uboot 环境变量实现简析                                                          ----------基于u-boot-2010.03 ...
  • sfrysh
  • sfrysh
  • 2011年10月29日 14:23
  • 4396

ffmpeg源码简析(三)av_malloc(),AVIOContext,AVFrame,avio_open2()等

内存操作的常见函数位于libavutil\mem.cav_malloc()av_malloc()是FFmpeg中最常见的内存分配函数。av_malloc()的代码可以简化成如下形式。void *av_...
  • King1425
  • King1425
  • 2017年04月24日 17:07
  • 743

ffmpeg源码简析(八)解码 av_read_frame(),avcodec_decode_video2(),avformat_close_input()

1.av_read_frame()av_read_frame()的作用是读取码流中的音频若干帧或者视频一帧。例如,解码视频的时候,每解码一个视频帧,需要先调用 av_read_frame()获得一帧视...
  • King1425
  • King1425
  • 2017年04月24日 20:42
  • 928
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Boost源码简析系列——timer(2)
举报原因:
原因补充:

(最多只允许输入30个字)