zoukankan      html  css  js  c++  java
  • C++11标准库chrono库使用

    chrono是C++11新加入的方便时间日期操作的标准库,它既是相应的头文件名称,也是std命名空间下的一个子命名空间,所有时间日期相关定义均在std::chrono命名空间下。通过这个新的标准库,可以非常方便进行时间日期相关操作。
    chrono库主要包含了三种类型:duration, time_point 和 clock。

    Duration(时间间隔)

    chrono库中用一个duration模板类,用来表示一段时间间隔,可以表示几秒钟、几分钟或者几个小时的时间间隔。

    原型

    template<typename _Rep, typename _Period = ratio<1>>
    struct duration
    {
    typedef _Rep   rep;
    ...
    private:
        rep  __r;  //内部维护的计数个数成员
    ...
    };

    第一个模版参数是数值类型,表示时钟个数;第二个为std::ratio,用来表示每个时钟的周期(单位为秒)
    ratio的原型是

    template<intmax_t _Num, intmax_t _Den = 1>
    struct ratio;

    这是一个非类型模版参数的模版类,intmax_t是定义在cstdint头文件中的内置类型。第一个参数代表分子,第二个代表分母,两者表示一个通用的比率类型。它们必须在编译期间确定为常量值。分母默认为1,因此ratio<60>代表60,ratio<1, 1000>代表0.001。为了方便使用,在ratio头文件中定义了常用比率的别名:

      typedef ratio<1,       1000000000000000000> atto;
      typedef ratio<1,          1000000000000000> femto;
      typedef ratio<1,             1000000000000> pico;
      typedef ratio<1,                1000000000> nano;
      typedef ratio<1,                   1000000> micro;
      typedef ratio<1,                      1000> milli;
      typedef ratio<1,                       100> centi;
      typedef ratio<1,                        10> deci;
      typedef ratio<                       10, 1> deca;
      typedef ratio<                      100, 1> hecto;
      typedef ratio<                     1000, 1> kilo;
      typedef ratio<                  1000000, 1> mega;
      typedef ratio<               1000000000, 1> giga;
      typedef ratio<            1000000000000, 1> tera;
      typedef ratio<         1000000000000000, 1> peta;
      typedef ratio<      1000000000000000000, 1> exa;

    回到duration模板类,默认的比率为ratio<1>,也就是一个时钟数_Rep代表1秒。为了方便使用,chrono库定义了如下的常用时间单位:

    /// nanoseconds
    typedef duration<int64_t, nano>     nanoseconds;
    
    /// microseconds
    typedef duration<int64_t, micro>    microseconds;
    
    /// milliseconds
    typedef duration<int64_t, milli>    milliseconds;
    
    /// seconds
    typedef duration<int64_t>       seconds;
    
    /// minutes
    typedef duration<int, ratio< 60>>   minutes;
    
    /// hours
    typedef duration<int, ratio<3600>>  hours;

    通过定义上述常用类型,可以非常方便的使用:

    //线程休眠10秒
    std::this_thread::sleep_for(std::chrono::seconds(10));

    成员

    duration内部维护了周期个数rep和周期period,两者结合用来表示间隔时间。

    count

    用来获取内部维护的rep类型的周期个数,或称为tick数。即定义变量的实参

    chrono::milliseconds ms(10);//10个tick
    chrono::duration<double, std::ratio<1, 30>> dur(10.5);//10.5 tick
    cout << "ms: " << ms.count() << '	' << "dur: "<< dur.count() << endl;

    上述代码输出:

    ms: 10 dur : 10.5

    静态成员函数

    duration实例化后,对于给定的rep表示周期个数的类型,提供了min、max和zero三个静态成员函数,用来获取当前类型能表示的最小、最大周期数和0周期数代表的duration对象。

    cout << chrono::seconds::max().count() << endl;

    //输出结果为:9223372036854775807

    运算操作

    duration支持基本所有算术运算操作,而且不同单位之间的可以自动进行匹配。这是通过duration_cast模板类实现的。

    chrono::minutes t1(5);
    chrono::seconds t2(30);
    chrono::seconds t3 = t1 - t2;
    cout << t3.count() << '	' << chrono::duration_cast<chrono::minutes>(t3).count() << endl;

    //对于类型转换会进行舍入
    //输出结果:270 4

    Time point

    chrono库中用一个time_point模板类,表示一个时间点,如生日、今天日落时刻等,通过一个相对epoch的时间间隔duration来实现,epoch就是1970-1-1时刻,对于同一个时钟来说,所有的time_point的epoch都是固定的。这个类可以与标准库ctime结合起来显示时间,ctime内部的time_t类型就是代表这个秒数。

    原型

    template<typename _Clock, typename _Dur = typename _Clock::duration>
    struct time_point
    {
    typedef _Clock                      clock;
    typedef _Dur                        duration;
    typedef typename duration::rep              rep;
    typedef typename duration::period           period;
    private:
        duration __d; //维护的内部duration成员
    ...
    
    };

    第一个参数为当前计时使用的时钟,可选为“system_colck”、“steady_colck”、“high_resolution_clock”或者是自定义的时钟类;
    第二个参数为时间间隔,默认为使用的时钟相同的间隔。
    内部维护了一个duration私有成员,通过制定的时钟,来确定距离epoch时间点的间隔。

    成员

    chrono::time_point<system_clock> tp = chrono::system_clock::now();
    cout << tp.time_since_epoch().count() << endl;

    //输出为:1452672734311762303
    //system_clock的ratio为nano

    运算

    与duration类似,time_point也提供了静态成员min和max,以及算术运算操作,这些都是通过内部维护的duration成员进行的,duration成员的各种操作由前面所述的提供保障,time_point就只需要通过time_since_epoch获取私有duration成员进行调用即可。还提供了与duration直接进行”+=”和“-=”的运算操作,对于普通的算术运算,如果有一个操作数类型为duration,则是在time_point类型操作数内部维护的duration成员上进行操作,则返回类型为time_point;当两者均为time_point类型时,返回类型为二者维护的duration成员之差,从而返回类型也为duration。

    表示当前系统时钟,共有三种:

    • system_clock:从系统获取时钟
    • steady_clock:不能被修改的时钟
    • high_resolution_clock:高精度时钟,实际上是system_clock或者steady_clock的别名,最小精度是纳秒

    system_clock

    system_clock 提供三个静态的函数,可以用于time_point提供了与C API的时间交互的良好定义。因此,可以很容易与time_t类型打交道。接口函数如下:

    //get current time
    static time_point now() noexcept;
    
    //time_point conver to time_t
    static time_t to_time_t (const time_point& tp) noexcept;
    
    //convert time_t to time_oint
    std::chrono::system_clock::from_time_t
    static time_point from_time_t (time_t t) noexcept;

    system_clock 和ctime函数使用demo:

    
    #include <iostream>
    #include <ctime>
    #include <chrono>
    
    int main ()
    {
        using std::chrono::system_clock;
    
        std::chrono::duration<int,std::ratio<60*60*24> > one_day (1);
    
        //current time
        system_clock::time_point today = system_clock::now();
    
        //tomorrow time
        system_clock::time_point tomorrow = today + one_day;
    
        //convert time type   
        time_t tmTomorrow = system_clock::to_time_t ( tomorrow );
    
        //time string
        std::cout << "tomorrow will be: " << ctime(&tmTomorrow);
    
        struct tm *p;   
        p = localtime(&tmTomorrow); /*转换为struct tm结构的当地时间*/  
        printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); 
    
        return 0;
    }

    运行结果:

    tomorrow will be: Sun Feb 11 09:13:07 2018
    2018/2/11 

    steady_clock

    steady_clock 专门用于计算时间差的工具,steady_clock 类只有一个静态函数now(),用于获取当前的时间,计算时间差的方式如下:

    #include <iostream>
    #include <chrono>
    
    int main()
    {
        typedef std::chrono::steady_clock  STEADY_CLOCK;
    
        STEADY_CLOCK::time_point t1 = STEADY_CLOCK::now();
    
        std::cout << "print 1000 stars" << std::endl;
    
        for (int i=1; i<=1000; ++i)
        {
            std::cout << "*";
            if (0 == i % 50) 
            {
                std::cout << "
    ";
            }
        }
    
        std::cout << std::endl;
    
        STEADY_CLOCK::time_point t2 = STEADY_CLOCK::now();
    
        //毫秒
        std::chrono::duration<double, std::milli> dTimeSpan = std::chrono::duration<double,std::milli>(t2-t1);
    
        std::cout << "print start time span : " << dTimeSpan.count() << "ms
    ";   
    }

    运行结果:

    print 1000 stars
    ****************************....
    print start time span : 0.091333ms

    参考资料:
    http://www.cplusplus.com/reference/chrono/
    http://blog.csdn.net/u010487568/article/details/50512770

  • 相关阅读:
    第二次冲刺 站立会议7
    第二次冲刺 站立会议6
    第二次冲刺 站立会议5
    第二次冲刺 站立会议4
    第二次冲刺 站立会议3
    第二次冲刺 站立会议2
    第二次冲刺 站立会议1
    第一次冲刺 站立会议9
    第一次冲刺 站立会议8
    第一次冲刺 站立会议7
  • 原文地址:https://www.cnblogs.com/jinxiang1224/p/8468162.html
Copyright © 2011-2022 走看看