深入理解 C++ 中 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

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值