zoukankan      html  css  js  c++  java
  • 深入理解std::chrono的时钟Clock

    std::chrono是C++11引入的日期时间处理库,其中包含3种时钟:system_clock,steady_clock,high_resolution_clock。近来需要使用高精度时间,很自然想到使用high_resolution_clock,然而使用后发现并非预期的得到自1970/1/1零点之后的计数,而是一个小得多的数字。那么这三种时钟有什么区别,用在什么情况下,我们来一探究竟。

    问题

    auto tp = std::chrono::high_resolution_clock::now();
    std::cout << tp.time_since_epoch().count() << std::endl;
    

    上述代码输出一个比较小的数字,high_resolution_clock的精度是纳秒,不可能是这么小的数字。

    三种时钟的区别

    所谓时钟,是指从一个时点开始,按照某个刻度的一个计数。如下代码摘自VC2017。

    • system_clock
    struct system_clock
    {	// wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime
    typedef long long rep;
    typedef ratio_multiply<ratio<_XTIME_NSECS_PER_TICK, 1>, nano> period;
    typedef chrono::duration<rep, period> duration;
    typedef chrono::time_point<system_clock> time_point;
    static constexpr bool is_steady = false;
    

    对于system_clock,其起点是epoch,即1970-01-01 00:00:00 UTC,其刻度是1个tick,也就是_XTIME_NSECS_PER_TICK纳秒。

    • high_resolution_clock
    typedef steady_clock high_resolution_clock;
    

    high_resolution_clock实际上和steady_clock一样。

    • steady_clock
    struct steady_clock
    {	// wraps QueryPerformanceCounter
    typedef long long rep;
    typedef nano period;
    typedef nanoseconds duration;
    typedef chrono::time_point<steady_clock> time_point;
    static constexpr bool is_steady = true;
    

    steady_clock的刻度是1纳秒,起点并非1970-01-01 00:00:00 UTC,一般是系统启动时间,这就是问题的关键。steady_clock的作用是为了得到不随系统时间修改而变化的时间间隔,所以凡是想得到绝对时点的用法都是错误的。steady_clock是没有to_time_t()的实现的,而system_clock是有的。

    三种时钟用在什么时候

    • system_clock:用在需要得到绝对时点的场景
    auto tp = std::chrono::system_clock::now();
    std::time_t tt = std::chrono::system_clock::to_time_t(tp);
    std::cout << tt << "seconds from 1970-01-01 00:00:00 UTC" << std::endl;
    
    • steady_clock:用在需要得到时间间隔,并且这个时间间隔不会因为修改系统时间而受影响的场景
    auto tp1 = std::chrono::steady_clock::now();
    //do something
    auto tp2 = std::chrono::steady_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>(tp2 - tp1).count() << "microseconds" << std::endl;
    
    • high_resolution_clock:high_resolution_clock是system_clock或steady_clock之一,根据情况使用

    常见的错误用法

    • std::this_thread::sleep_until传入的是steady_clock::time_point
    • 根据steady_clock::time_point得到time_t
  • 相关阅读:
    ubuntu 13.04 root权限设置方法详解
    观锁和乐观锁——《POJOs in Action》
    观锁与悲观锁(Hibernate)
    关于python的环境变量问题
    vs2010 调试快捷键
    VIM7.3中文手册
    Java最全文件操作实例汇总
    response letter模板
    数据库字段类型
    Tomcat系列之Java技术详解
  • 原文地址:https://www.cnblogs.com/zhongpan/p/7490657.html
Copyright © 2011-2022 走看看