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
  • 相关阅读:
    Unique Binary Search Trees——LeetCode
    Binary Tree Inorder Traversal ——LeetCode
    Maximum Product Subarray——LeetCode
    Remove Linked List Elements——LeetCode
    Maximum Subarray——LeetCode
    Validate Binary Search Tree——LeetCode
    Swap Nodes in Pairs——LeetCode
    Find Minimum in Rotated Sorted Array——LeetCode
    Linked List Cycle——LeetCode
    VR AR MR
  • 原文地址:https://www.cnblogs.com/zhongpan/p/7490657.html
Copyright © 2011-2022 走看看