• 深入理解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
  • 相关阅读:
    深入理解 IE haslayout
    electron的应用
    自动化批量录入Web系统
    Flask + Vue的一个示例
    如何从git仓库里下载单个文件夹
    Django项目设置首页
    简单更改Django Admin登录页面
    Flask web项目使用.flaskenv文件
    Flask 里url_for的使用
    使用Flask-migrate迁移数据库
  • 原文地址:https://www.cnblogs.com/zhongpan/p/7490657.html
Copyright © 2020-2023  润新知