c++ 标准库chrono 中duration、timepoint和clock的使用方法


C++标准库中的chrono库提供了时间计量的支持,包括用于测量时间段的duration类、用于表示时间点的time_point类,以及用于跟踪时间的时钟(clock)类。chrono库提供了高精度的时钟,允许用户测量程序执行的时间,或者实现精确的时间戳。同时,chrono库还提供了一些辅助函数,帮助我们完成时间计算、格式化时间的操作。总之,chrono库是一个非常实用的工具库,可以帮助我们方便地处理时间相关的问题。要学习chrono,就得从分数开始,分数是chrono库的基石,让我们开始吧。

std::ratio<> 编译期的分数运算,并且把结果降至最简式

ratio 定义

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 小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 不能做编译期运算
}

输出

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

ratio 类型四则运算以及大小比较(编译期进行)

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

标准库定义的一些ratio

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 库一览

duration 时间段
tick 片刻数
timepoint 时间点
epoch 起始点
clock 时钟

时间段duration 说白了就是一个时间单位的片刻数,我们以秒为单位,那么一分钟是60秒,那么时间段也就是60秒,这里的60就是片刻数。
时间点timepoint 就是始点epoch和时间段duration的组合,比如起始点为中午12点,经过时间段2个小时,那么就是下午2点钟了,比12点早两个小时,那么就是早上12点了。
clock 时钟是个对象,它定义了timepoint的起始点和一个tick周期,不同的时钟有不同的起始点,比如system_clock 起始点为1970年1月1日,tick 周期可能是100纳秒,看实现咯
他们关联具体看下图:
时间段、时间点、起始点、时钟的关系(图片来源于c++标准库第二版)

duration(时间段)

  1. 定义
    duration 是tick 和一个分数ratio(单位时间秒)的组合,如:
    template <class _Rep, class _Period = ratio<1>>
    class duration;
    
    其中ratio<1>是ratio<1, 1> 也就是1/1 代表的是秒,_Rep代表是有多少个片刻,也就是多少个秒。如:
    // duration<60> 等于 duration<60, ratio<1,1>>  60个一秒也就是代表一分钟,意味着这个时间段是一分钟。
    std::chrono::duration<60> oneMinute;
    std::chrono::duration<60> sixtysecond;
    
  2. 我们试着使用duration 来表示时 分 秒
    #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;
    }
    
    输出
    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. c++ 标准库定义了常用的时分秒 微秒 纳秒等数据
    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 构造以及公开成员及成员方法
    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
    
    一些时间的构造以及隐式转换举例
    #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. duration 的计算
    duration 的加减乘除都是返回duration ,如果两个duration 不同,会自动进行自动转换之后在相加减,比如小时和分钟相加,最后是得到分钟的duration,反之则不行,因为分钟不能隐式转换为小时
    d1 + d2 返回相加之后的duration
    d1 - d2 返回相减后的duration
    d1 / d2 返回rep 类型 相除的duration,代表两个duration差多少倍,
    d1 % d2 两个duration取余
    d % value 返回duration,对某个值取余
    d * value tick * 一个数据,也就是duration::count() 得到的数扩大value倍
    value * d 也就是duration::count() 得到的数扩大value倍
    d / value duration::count() 得到的数缩小value倍
    d1 == d2 返回bool,两个duration相等
    d1 != d2 返回bool,两个duration不等
    d1 < d2 返回bool,小于
    d1 <= d2 返回bool,小于等于
    d1 > d2 返回bool,大于
    d1 >= d2 返回bool,大于等于
    ++d tick++ 返回duration, 先加后运算
    d++ tick++ 返回duration,先运算再加
    –d tick-- 返回duration,先减后运算
    d-- tick-- 返回duration,先运算后减
    d += d1 返回duration,同加法
    d -= d1 返回duration, 同减法
    d *= value 返回duration,同乘一个数
    d /= value 返回duration,同除一个数
    d %= value 返回duration,同取余运算
    d %= d1 同返回duration,取余运算\
        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;
    
    输出
    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
    
    这里的取余运算,我们可以把小单位转换成不同的单位,并且保留精度,比如我们%minutes 可以得到秒钟余数, 我们取余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;
    
    }
    
    输出
    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(时钟)和时间点(timepoint)

clock 定义一个起始点epoch,和tick周期,比如起始点为程序的开始,tick为纳秒的时钟
timepoint 是clock 是起始点向前或者向后的一段duration。
两者的关联

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

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
            ...
        }
    }
}

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 示例代码

/ 定义我们自己的时间输出函数
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;
}

输出

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

标准库的三个时钟

  1. std::chrono::system_clock 系统时钟,将timepoint关联到系统时钟上,他是不稳定的时钟,如果用户修改了系统时间,那么它会被修改
    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 稳定时钟,他能保证时间稳定的流逝,不会被修改,可能是程序启动的时间,也有可能是系统启动的时间
    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 表示系统中拥有最短tick 周期的clock 一般是纳秒,也不排除有些系统是毫秒的。
    namespace std
    {
          
          
        namespace chrono
        {
          
          
            // 可能的实现 哈哈
            using high_resolution_clock = steady_clock;
        }
    }
    

标准库中data/time相关的函数

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;
}

输出

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

可以看出tick 不一样了,这是因为啊,time_t 时间单位是秒,相当于秒后面的数据就被抹杀了,转换有精度损失,可以看下from_time_t的实现
使用了t(d) 使用了duration 构造,本来是100纳秒,转为秒,肯定是有精度损失的。
time_point{seconds{_Tm}};

综合运用

假如我们要开发一个渲染软件,那么肯定会和帧率挂钩了,就是每秒钟我们需要稳定的输出多少张图片,或者是在屏幕上绘制多少张画面,比如33张,那么我们就可以说fps为33
那我们如和在一个循环中保证每一秒钟运行33次呢,答案就是让线程睡眠cpu用不掉的时机,比如fps是33,那么一秒钟运行33次,运行的时间是30毫秒多点, 那假设cpu才耗费20毫秒,
还有十毫秒,那我们就得睡眠十毫秒,但是问题就在这里,cpu并不是每次都消耗20毫秒,有可能一次消耗10 ,一次消耗15,一次消耗20是,那么我们就需要一个期望时间,
期望时间 = currentTimepoint + duration(30ms);
睡眠时间 = 期望时间 - 运行耗时
具体看demo

#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;
}

输出

----------------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

猜你喜欢

转载自blog.csdn.net/qq_33944628/article/details/130396296
今日推荐