How to use duration, timepoint and clock in the c++ standard library chrono


The chrono library in the C++ standard library provides support for time measurement, including the duration class for measuring time periods, the time_point class for representing time points, and the clock class for tracking time. The chrono library provides a high-precision clock, allowing users to measure the time of program execution or achieve precise timestamps. At the same time, the chrono library also provides some auxiliary functions to help us complete time calculation and format time operations. In short, the chrono library is a very practical tool library that can help us deal with time-related issues conveniently. To learn chrono, you have to start with scores. Scores are the cornerstone of the chrono library. Let's get started.

std::ratio<> compile-time fractional operation and reduce the result to the simplest form

ratio definition

typedef long long intmax_t; // 位于stdint.h中
namespace std{
    
    
    template <intmax_t N, intmax_t D = 1>
    struct ratio {
    
     
        static constexpr intmax_t num; // 分子
        static constexpr intmax_t den; // 分母 denominator
        using type = ratio<num, den>;
    };
}

ration small demo

#include <chrono>
#include <stdio.h>
int main()
{
    
    
    std::ratio<3, 5> three_five;
    printf("%lld/%lld\n", three_five.num, three_five.den);
    std::ratio<30, 50> tf;
    printf("%lld/%lld\n", tf.num, tf.den);
    std::ratio<5, -3> five_three;
    printf("%lld/%lld\n", five_three.num, five_three.den);
    std::ratio<-50, 30> ft;
    printf("%lld/%lld\n", ft.num, ft.den);

    int a = 0;
    int b = 1;
    //std::ratio<a, b> a_b; 编译错误,因为a, b 不能做编译期运算
}

output

3/5
3/5
5/3
5/3

Four arithmetic operations of ratio type and size comparison (performed at compile time)

std::ratio_add          求和        结果为std::ratio<>
std::ratio_subtract     求差        结果为std::ratio<>
std::ratio_multiply     乘法求积    结果为std::ratio<>
std::ratio_divide       除法求商    结果为std::ratio<>
std::ratio_equal             相等        结果为true_type 或者 false_type
std::ratio_not_equal         不相等      结果为true_type 或者 false_type
std::ratio_less              小于        结果为true_type 或者 false_type
std::ratio_less_equal        小于等于    结果为true_type 或者 false_type
std::ratio_greater           大于        结果为true_type 或者 false_type
std::ratio_greater_equal     大于等于    结果为true_type 或者 false_type

Some ratios defined by the standard library

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

chrono library overview

duration time period
tick number of moments
timepoint time point
epoch starting point
clock clock

To put it bluntly, time period duration is the number of moments in a time unit. We use seconds as the unit, so one minute is 60 seconds, then the time period is 60 seconds, and 60 here is the number of moments.
The time point is the combination of the starting point epoch and the time period duration. For example, the starting point is 12 noon, and after 2 hours of the time period, it is 2 o'clock in the afternoon. If it is two hours earlier than 12 o'clock, then it is 12 o'clock in the morning. .
clock The clock is an object, which defines the starting point of timepoint and a tick period. Different clocks have different starting points. For example, the starting point of system_clock is January 1, 1970, and the tick period may be 100 nanoseconds. It depends on the implementation
. See the figure below for details:
The relationship between time period, time point, starting point and clock (picture comes from c++ standard library second edition)

duration(time period)

  1. Define
    duration as a combination of tick and a fraction ratio (unit time seconds), such as:
    template <class _Rep, class _Period = ratio<1>>
    class duration;
    
    Among them, ratio<1> is ratio<1, 1>, that is, 1/1 represents seconds, and _Rep represents the number of moments, that is, the number of seconds. like:
    // duration<60> 等于 duration<60, ratio<1,1>>  60个一秒也就是代表一分钟,意味着这个时间段是一分钟。
    std::chrono::duration<60> oneMinute;
    std::chrono::duration<60> sixtysecond;
    
  2. We try to use duration to represent hours, minutes and seconds
    #include <chrono>
    #include <stdio.h>
    #include <iostream>
    // 定义我们自己的时间输出函数
    template <typename V, typename R>
    std::ostream &operator << (std::ostream &s, const std::chrono::duration<V, R> &d)
    {
          
          
        s << "tick:" << d.count() << " period:" << R::num << "/" << R::den ;
        return s;
    }
    int main()
    {
          
          
        // 1000ns = 1μs
        // 1000μs = 1ms
        // 1000ms = 1s
        // 60s = 1minute
    
        std::chrono::duration<int, std::ratio<1, 1>> s(1); // 1秒钟
        std::cout << "s\t" << s << std::endl;
        std::chrono::duration<int, std::ratio<1, 1000>> ms(1); // 1毫秒
        std::cout << "ms\t" << ms << std::endl;
        std::chrono::duration<int, std::ratio<1, 1000000>> us(1);// 1微妙
        std::cout << "us\t" << us << std::endl;
        std::chrono::duration<int, std::ratio<1, 1000000000>> ns(1); // 1纳秒
        std::cout << "ns\t" << ns << std::endl;
    
        std::chrono::duration<int, std::ratio<60, 1>> minutes(1); // 1分钟
        std::cout << "minutes\t" << minutes << std::endl;
        std::chrono::duration<int, std::ratio<60 * 60, 1>> hour(1); // 1小时
        std::cout << "hour\t" << hour << std::endl;
        std::chrono::duration<int, std::ratio<60 * 60 * 24, 1>> day(1); // 1天
        std::cout << "day\t" << day << std::endl;
        std::chrono::duration<int, std::ratio<60 * 60 * 24 * 30, 1>> mouth(1); // 1个月
        std::cout << "mouth\t" << mouth << std::endl;
    }
    
    output
    s       tick:1 period:1/1
    ms      tick:1 period:1/1000
    us      tick:1 period:1/1000000
    ns      tick:1 period:1/1000000000
    minutes tick:1 period:60/1
    hour    tick:1 period:3600/1
    day     tick:1 period:86400/1
    mouth   tick:1 period:2592000/1
    
  3. The c++ standard library defines commonly used data such as hours, minutes, seconds, microseconds, and nanoseconds.
    namespace std
    {
          
          
        namespace chrono
        {
          
          
            using nanoseconds  = duration<long long, nano>;
            using microseconds = duration<long long, micro>;
            using milliseconds = duration<long long, milli>;
            using seconds      = duration<long long>; // = duration<long long, ratio<1,1>>
            using minutes      = duration<int, ratio<60>>;
            using hours        = duration<int, ratio<3600>>;
    #if _HAS_CXX20
            using days   = duration<int, ratio_multiply<ratio<24>, hours::period>>;
            using weeks  = duration<int, ratio_multiply<ratio<7>, days::period>>;
            using years  = duration<int, ratio_multiply<ratio<146097, 400>, days::period>>;
            using months = duration<int, ratio_divide<years::period, ratio<12>>>;
    #endif // _HAS_CXX20
        }
    }
    
  4. duration constructor and public members and member methods
    duration d          构造空的duration
    duration d2(d)      拷贝构造 d可能拥有不同period
    duration d(value)   使用d这种时间类型构建一个tick 为value 的duration
    d = d2              将d2 赋值给d 这里可能存在隐士转换
    d.count()           返回d的片刻数
    duration_cast<D>(d) 将d强转为D类型
    duration::zero()    获取长度为0的duration
    duration::max()     返回这种类型最大的duration
    duration::mmin()    返回这种类型最小的duration
    duration::rep       rep 的类型
    duration::period    period的类型,类型是ratio
    
    Some time construction and implicit conversion examples
    #include <chrono>
    #include <stdio.h>
    #include <iostream>
    // 定义我们自己的时间输出函数
    template <typename V, typename R>
    std::ostream &operator << (std::ostream &s, const std::chrono::duration<V, R> &d)
    {
          
          
        s << "tick:" << d.count() << " period:" << R::num << "/" << R::den ;
        return s;
    }
    int main()
    {
          
          
        // 如果还是不能理解std::chrono::  seconds、minutes 等的表示,可以直接把tick 理解为秒钟在转换对应的时分秒
        std::chrono::duration<int> d(20);
        std::cout << d << std::endl;
        std::chrono::seconds sec(60);
        std::cout << sec << std::endl;
        // std::chrono::minutes min = sec; 不能隐式转换为分钟,因为有精度丢失
        // 使用duration_cast 强转
        std::chrono::minutes min = std::chrono::duration_cast<std::chrono::minutes>(sec);
        std::cout << min << std::endl;
    
        // 不足一分钟强转
        sec = std::chrono::seconds(20);
        // 此处存在精度损失 不足一分钟是0分钟
        std::cout << std::chrono::duration_cast<std::chrono::minutes>(sec) << std::endl;
    
        // 可以把大单位转为小单位 例如可把分钟隐式转为秒钟
        std::chrono::seconds s = min;
        std::cout << s << std::endl;
        std::cout << std::chrono::seconds(std::chrono::minutes(3));
    }
    
  5. The calculation of duration
    , addition, subtraction, multiplication and division of duration all return duration. If the two durations are different, they will be automatically converted and then added and subtracted. For example, hours and minutes are added together, and finally the duration of minutes is obtained. The opposite is not possible, because minutes Cannot be implicitly converted to hours
    d1 + d2 Returns the duration after addition
    d1 - d2 Returns the duration after subtraction
    d1 / d2 Returns the duration of rep type division, representing how many times the two durations differ,
    d1 % d2 The two durations are taken Remainder
    d % value returns duration, and the remainder of a certain value is
    d * value tick * a piece of data, that is, the number obtained by duration::count() is expanded by value times
    value * d, that is, the number obtained by duration::count() is expanded value times
    d / value duration::count() The obtained number is reduced by value times
    d1 == d2 Returns bool, the two durations are equal
    d1 != d2 Returns bool, the two durations are not equal
    d1 < d2 Returns bool, less than
    d1 <= d2 returns bool, less than or equal to
    d1 > d2 returns bool, greater than
    d1 >= d2 returns bool, greater than or equal to
    ++d tick++ returns duration, adds first and then operates
    d++ tick++ returns duration, operates first and then adds
    –d tick-- returns duration, subtracts first and then calculates
    d-- ​​tick-- returns duration, calculates first and then subtracts
    d += d1 returns duration, same as addition
    d -= d1 returns duration, same as subtraction
    d *= value returns duration, Multiply a number
    d /= value to return duration, divide a number
    d %= value to return duration, and perform remainder operation
    d %= d1 Return duration to perform remainder operation\
        std::chrono::minutes d1(60);
        std::chrono::seconds d2(60);
        std::chrono::seconds d(20);
        std::cout << "d1 + d2 \t" << d1 + d2 << std::endl;
        std::cout << "d1 - d2 \t" << d1 - d2 << std::endl;
        std::cout << "d1 / d2 \t" << d1 / d2 << std::endl;
        std::cout << "d2 / d1 \t" << d2 / d1 << std::endl; // 小除以大,进度损失为0
        std::cout << "d1 % d2 \t" << d1 % d2 << std::endl;
        std::cout << "d * 2   \t" <<d * 2 << std::endl;
        std::cout << "2 * d   \t" << 2 * d<< std::endl;
        std::cout << "d1 % d2 \t" << d1 % d2 << std::endl;
        std::cout << "d / 2   \t" << d / 2 << std::endl;
        std::cout << "d1 == d2 \t" << (d1 == d2) << std::endl;
        std::cout << "d1 != d2 \t" << (d1 != d2) << std::endl;
        std::cout << "++d \t" << ++d << std::endl;
        std::cout << "d++ \t" << d++ << std::endl;
        auto d3 = d + d1;
        std::cout << "d3 \t" << d3 << std::endl;
        d3 += d;
        std::cout << "d3 \t" << d3 << std::endl;
    
    output
    d1 + d2         tick:3660 period:1/1
    d1 - d2         tick:3540 period:1/1
    d1 / d2         60
    d2 / d1         0
    d1 % d2         tick:0 period:1/1
    d * 2           tick:40 period:1/1
    2 * d           tick:40 period:1/1
    d1 % d2         tick:0 period:1/1
    d / 2           tick:10 period:1/1
    d1 == d2        0
    d1 != d2        1
    ++d     tick:21 period:1/1
    d++     tick:21 period:1/1
    d3      tick:3622 period:1/1
    d3      tick:3644 period:1/1
    
    For the remainder operation here, we can convert small units into different units and retain the accuracy. For example, we can get the remainder of seconds by using %minutes, and we can get the remainder of milliseconds by taking the remainder of second.
    #include <chrono>
    #include <stdio.h>
    #include <iostream>
    
    // 定义我们自己的时间输出函数
    template <typename V, typename R>
    std::ostream &operator << (std::ostream &s, const std::chrono::duration<V, R> &d)
    {
          
          
        s << "tick:" << d.count() << " period:" << R::num << "/" << R::den ;
        return s;
    }
    
    int main()
    {
          
          
        // 定义20ms * 30s * 3minute
        std::chrono::milliseconds ms(20 + 30 * 1000 + 3 * 60 * 1000);
        // 分钟直接转换
        auto mm = std::chrono::duration_cast<std::chrono::minutes>(ms);
        // 取余分钟可得秒钟余数
        auto second = std::chrono::duration_cast<std::chrono::seconds>(ms % std::chrono::minutes(1));
        std::cout << "total ms=" << ms << std::endl;
        std::cout << "minutes=" << mm << std::endl <<
            "second=" << second << std::endl <<
            // 取余秒钟数可得毫秒余数
            "millisecond=" << ms % std::chrono::seconds(1) << std::endl;
    
    }
    
    output
    total ms=tick:210020 period:1/1000
    minutes=tick:3 period:60/1
    second=tick:30 period:1/1
    millisecond=tick:20 period:1/1000
    

clock and timepoint

clock defines a starting point epoch, and a tick period. For example, the starting point is the beginning of the program, and the tick is the clock timepoint in nanoseconds. The
clock is a duration forward or backward from the starting point.
The connection between the two

clock 
clock::duration     获取clock的duraion类型
clock::rep          获取tick的类型,等价于clock::duration::rep
clock::period       获取period类型,等价于clock::ruration::period 
clock::time_point   获取clock的timepoint 类型
clock::now          静态方法,得到一个表示现在时间点的tiem_point

timepoint
time_point::clock  关联的时钟类型
time_point::duration 关联的时钟duration
time_point::time_since_epoch 表示clock 的起始点到现在时间点经过的duration

Definition of timepoint

namespace std
{
    
    
    namespace chrono
    {
    
    
        template <class _Clock, class _Duration = typename _Clock::duration>
        class time_point
        {
    
    
            using clock    = _Clock; // 时钟类型
            using duration = _Duration; // 时间段类型
            using rep      = typename _Duration::rep; 
            using period   = typename _Duration::period;
            time_point(); // 默认构造
            time_point(const _Duration& _Other); // 拷贝构造
            ime_point(const time_point<_Clock, _Duration2>& _Tp); // 用clock 的起始点构造duration 之后的时间点
            _Duration time_since_epoch(); // 起始点到现在时间点经过的duration
            ...
        }
    }
}

Various operations of timepoint

//1. 构造
timepoint t 使用clock 提供的epoch 构造一个timepoint
timepoint t(tp1) 拷贝构造
timepoint t(d) 使用clock 提供的epoch 构造一个duration 后timepoint
time_point_cast<C, D>(t) 时间点的转换,可以抓换为不同时钟和不同的duration

// 计算 只有加减运算,且只能和duration 和timpoint 计算
t += d 返回新的timepoint,值为t + duration
t -= d 返回新的timepoint,值为t - duration
t +  d 返回新的timepoint,值为t + duration
d +  t 返回新的timepoint,值为t + duration
t -  d 返回新的timepoint,值为t - duration
t1 - t2 返回duration  值为两个时间点之间的duration

// 比较 只能是时间点与时间点比较
t1 == t2  返回bool
t1 != t2  返回bool
t1 <  t2  返回bool
t1 <= t2  返回bool
t1 >  t2  返回bool
t1 >= t2  返回bool

// public成员
t.time_since_epoch() 返回duration,值为epoch 和timepoint 之间的时间段

timepoint::min() 返回timepoint, 得到最小的时间点
timepoint::max() 返回timepoint, 返回最大的时间点

timepoint sample code

/ 定义我们自己的时间输出函数
template <typename V, typename R>
std::ostream &operator << (std::ostream &s, const std::chrono::duration<V, R> &d)
{
    
    
    s << "tick:" << d.count() << " period:" << R::num << "/" << R::den ;
    return s;
}


int main()
{
    
    
    // 使用精准时钟
    using timepoint = std::chrono::time_point<std::chrono::steady_clock>;
    timepoint t;
    std::cout << "t  info" << t.time_since_epoch() << std::endl;
    timepoint t1(timepoint::duration(5000));
    std::cout << "t1 info" << t1.time_since_epoch() << std::endl;
    t += timepoint::duration(2000);
    std::cout << "t  info" << t.time_since_epoch() << std::endl;
    auto t2 = t + timepoint::duration(2000);
    std::cout << "t2 info" << t2.time_since_epoch() << std::endl;

    // 比较
    std::cout << "t1 == t2 \t" << (t1 == t2) << std::endl;
    std::cout << "t1 != t2 \t" << (t1 != t2) << std::endl;
    std::cout << "t1 <  t2 \t" << (t1 < t2) << std::endl;
    std::cout << "t1 <= t2 \t" << (t1 <= t2) << std::endl;
    std::cout << "t1 >  t2 \t" << (t1 > t2) << std::endl;
    std::cout << "t1 >= t2 \t" << (t1 >= t2) << std::endl;
    // 最大最小
    std::cout << "min info" << timepoint::min().time_since_epoch() << std::endl;
    std::cout << "mac info" << timepoint::max().time_since_epoch() << std::endl;
    return 0;
}

output

t  infotick:0 period:1/1000000000
t1 infotick:5000 period:1/1000000000
t  infotick:2000 period:1/1000000000
t2 infotick:4000 period:1/1000000000
t1 == t2        0
t1 != t2        1
t1 <  t2        0
t1 <= t2        0
t1 >  t2        1
t1 >= t2        1
min infotick:-9223372036854775808 period:1/1000000000
mac infotick:9223372036854775807 period:1/1000000000

Three clocks from the standard library

  1. std::chrono::system_clock system clock, associates timepoint with the system clock. It is an unstable clock. If the user modifies the system time, it will be modified.
    namespace std
    {
          
          
        namespace chrono
        {
          
          
            struct system_clock {
          
          
                using rep                       = long long;
                using period                    =  ratio<1, 10'000'000>; // 100 nanoseconds
                using duration                  =  duration<rep, period>;
                using time_point                =  time_point<system_clock>;
                static constexpr bool is_steady = false; // 不稳定时钟
                static time_point now(); // 当前时间
                static __time64_t to_time_t(const time_point& _Time); // 把时间点转为数值,转为std::time_t
                static time_point from_time_t(__time64_t _Tm); // 把一个数值转为时间点 std::time_t 转为timepoint
            };
        }
    }
    
  2. std::chrono::steady_clock is a stable clock. It can ensure the stable passage of time and will not be modified. It may be the time when the program starts or the time when the system starts.
    namespace std
    {
          
          
        namespace chrono
        {
          
          
            struct steady_clock {
          
           // wraps QueryPerformanceCounter
                using rep                       = long long;
                using period                    = nano;
                using duration                  = nanoseconds;
                using time_point                = time_point<steady_clock>;
                static constexpr bool is_steady = true; // 是稳定时钟
                static time_point now(); // 返回现在的时间点
        };
        }
    }
    
  3. std::chrono::high_resolution_clock indicates the clock with the shortest tick period in the system, which is generally nanoseconds, and it is not excluded that some systems are milliseconds.
    namespace std
    {
          
          
        namespace chrono
        {
          
          
            // 可能的实现 哈哈
            using high_resolution_clock = steady_clock;
        }
    }
    

Data/time related functions in the standard library

std::clock_t 数值类型,用来表示cpu 消逝时间,由std::clock()返回
std::time_t 数值类型, 表示timepoint
struct tm   结构体, 包含时分秒 年月日 星期 一年中的第几天 
std::clock() 获取cpu 消耗时间
std::time() 返回数值类型,获取当前时间
std::difftime() 两个time_t之间的插,double类型,单位秒
std::localtime() 使用本地时区把time_t 转为一个tm
std::gmtime() 不考虑时区,把time_t 转为tm
std::asctime() 把tm 转为标准日志格式化字符串
std::strftime() 把tm 转化为用户自定义的日历时间格式化字符串
std::ctime() 转换time_t 为标准日历时间,并且考虑时区,等于 asctime(localtime(time_t))
std::mktime() 转换tm 为time_t
#include <chrono>
#include <stdio.h>
#include <iostream>
#include <ctime>

// 定义我们自己的时间输出函数
template <typename V, typename R>
std::ostream &operator << (std::ostream &s, const std::chrono::duration<V, R> &d)
{
    
    
    s << "tick:" << d.count() << " period:" << R::num << "/" << R::den ;
    return s;
}


int main()
{
    
    
    // 时间点
    auto t = std::chrono::system_clock::now();
    std::cout << "now " << t.time_since_epoch() << std::endl;
    // 把时间点转为time_t
    std::time_t st = std::chrono::system_clock::to_time_t(t);
    // 把time_t 转为std::tm
    struct std::tm  *stm = std::localtime(&st);
    if (stm)
    {
    
    
        printf("%d-%d-%d %d:%d:%d\n",
            stm->tm_year, stm->tm_mon, stm->tm_mday, stm->tm_hour, stm->tm_min, stm->tm_sec);
    }
    // 把tm 转为time_t
    std::time_t st1 = std::mktime(stm);
    // 把time_t 转为时间点
    auto tp = std::chrono::system_clock::from_time_t(st1);
    // 打印时钟
    std::cout << "now " << tp.time_since_epoch() << std::endl;
    return 0;
}

output

now tick:16824202401983799 period:1/10000000
123-3-25 18:57:20
now tick:16824202400000000 period:1/10000000

It can be seen that the tick is different. This is because the time unit of time_t is seconds, which means that the data after the second is erased. There is a loss of precision in the conversion. You can see that the implementation of from_time_t uses t(d) and duration
. The structure is originally 100 nanoseconds, but when converted to seconds, there must be a loss of accuracy.
time_point{seconds{_Tm}};

Integrated use

If we want to develop a rendering software, it will definitely be linked to the frame rate, that is, how many pictures we need to stably output per second, or how many pictures to draw on the screen, such as 33, then we can say fps If it is 33
, then how can we ensure that it runs 33 times per second in a loop? The answer is to let the thread sleep when the CPU cannot use it. For example, if fps is 33, then it runs 33 times per second, and the running time is 30 A little more than 20 milliseconds, assuming that the CPU only consumes 20 milliseconds,
and there are still ten milliseconds, then we have to sleep for ten milliseconds, but the problem is here, the CPU does not consume 20 milliseconds every time, it may consume 10 at a time and 15 at a time. , consuming 20 at a time, then we need an expected time,
expected time = currentTimepoint + duration (30ms);
sleep time = expected time - running time,
see the demo for details

#include <iostream>
#include <chrono>
#include <thread>
 
int main()
{
    
    
    const int FRAMES_PER_SECOND = 33;
    const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND;
    
    std::chrono::steady_clock::time_point now, schedule;
    std::chrono::steady_clock::time_point fpsTime;
    int fps = 0;
    auto skip_time = std::chrono::milliseconds(SKIP_TICKS);
    auto deviation = std::chrono::milliseconds(3);
    auto oneSecond = std::chrono::milliseconds(1000);
    while (true)
    {
    
    
        now = std::chrono::steady_clock::now();
        schedule = now + skip_time;

        {
    
    
            // 做一些事情, 这里使用睡眠代替耗时
            std::this_thread::sleep_for(std::chrono::milliseconds(10));
        }

        // 此处now 是为了计算fps 是否超时
        now = std::chrono::steady_clock::now();
        // 这里只是为了打印fps ,具体业务可去掉
        if (now - fpsTime >= oneSecond)
        {
    
    
            printf("----------------fps:%d\n", fps);
            fpsTime = now;
            fps = 0;
        }
        fps++;
        now = std::chrono::steady_clock::now();
        // 计算应该睡眠几秒
        auto diff = schedule - now;
        // 睡眠修正后的时间
        if (diff >= deviation)
        {
    
    
            std::this_thread::sleep_for(diff);
        }
    }
    return 0;
}

output

----------------fps:0
----------------fps:30
----------------fps:31
----------------fps:31
----------------fps:31
----------------fps:31
----------------fps:31
----------------fps:30
----------------fps:31
----------------fps:31
----------------fps:31
----------------fps:31
----------------fps:31

Guess you like

Origin blog.csdn.net/qq_33944628/article/details/130396296