chrono是c++ 11中的时间库,提供计时,时钟等功能。

学习chrono,关键是理解里面时间段(Durations)、时间点(Time points)的概念。

1.精度:

时钟节拍(时间精度):

template <intmax_t N, intmax_t D = 1> class ratio;

其中N表示分子,D表示分母,默认用秒表示的时间单位。

N对应于其成员num,D对应于其成员den

常用的单位:

ratio<60, 1>                    minute

ratio<1, 1>                      second

ratio<1, 1000>               microsecond

...

ratio主要是是为后面将要讲解的时间段,时间点等提供精度(单位)

[cpp] view plaincopyprint?
  1. #include<iostream>
  2. #include<chrono>
  3. using namespace std;
  4. int main()
  5. {
  6. cout << "millisecond : ";
  7. cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" <<endl;
  8. system("pause");
  9. return 0;
  10. }
#include<iostream>
#include<chrono>
using namespace std;
int main()
{
cout << "millisecond : ";
cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" <<endl;
system("pause");
return 0;
}

2.时间段:

template <class Rep, class Period = ratio<1> >
class duration;

std::chrono::duration 表示一段时间,比如两个小时,12.88秒,半个时辰,一炷香的时间等等

Rep表示一种数值类型,用来表示Period的数量,比如int float double。
Period是ratio类型,用来表示上面所说的单位精度,比如second milisecond。
chrono中宏定义了许多特例化了的duration:
就是常见的hours,miniutes,seconds,milliseconds等,使用std::chrono::milliseconds直接使用。
(1)构造函数很简单
[cpp] view plaincopyprint?
  1. (1)duration() = default;    //默认构造
  2. (2)duration (const duration& dtn);        //(2)(3)拷贝构造
  3. (3)template<class Rep2, class Period2>
  4. constexpr duration (const duration<Rep2,Period2>& dtn);
  5. (4)template<class Rep2>      //传递一个某类型(int等)的数值,构造一个时间段
  6. constexpr explicit duration (const Rep2& n);
(1)duration() = default;    //默认构造
(2)duration (const duration& dtn);        //(2)(3)拷贝构造
(3)template<class Rep2, class Period2>
constexpr duration (const duration<Rep2,Period2>& dtn);
(4)template<class Rep2>      //传递一个某类型(int等)的数值,构造一个时间段
constexpr explicit duration (const Rep2& n);

(2)成员函数count()返回单位时间的数量。

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include <chrono>
  3. int main()
  4. {
  5. std::chrono::milliseconds mscond(1000); // 1 second
  6. std::cout << mscond.count() << " milliseconds.\n";
  7. std::cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
  8. std::cout << " seconds.\n";
  9. system("pause");
  10. return 0;
  11. }
#include <iostream>
#include <chrono>
int main()
{
std::chrono::milliseconds mscond(1000); // 1 second
std::cout << mscond.count() << " milliseconds.\n";
std::cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
std::cout << " seconds.\n";
system("pause");
return 0;
}


(2)当不要求截断值的情况下(时转换成秒是没问题,但是秒转换成时就不行)时间段的转换是隐式
的。显示转换可以由 std::chrono::duration_cast<> 来完成。
比如 std::chrono::milliseconds ms(54802);

std::chrono::seconds s=std::chrono::duration_cast<std::chrono::seconds>(ms);

这里的结果就是截断的,而不是进行了舍入,所以s最后的值将为54。

3.时间点:

template <class Clock, class Duration = typename Clock::duration>
class time_point;

std::chrono::time_point 表示一个具体时间,如上个世纪80年代、今天下午3点、火车出发时间等,只要它能用计算机时钟表示。

第一个模板参数Clock用来指定所要使用的时钟(标准库中有三种时钟,system_clock,steady_clock和high_resolution_clock。见4时钟详解),第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration<> )

时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。

(1)构造函数:

(1)
time_point();           //默认构造函数,时间戳作为其值
(2)
template <class Duration2>
time_point (const time_point<clock,Duration2>& tp);  //拷贝构造函数
(3)
explicit time_point (const duration& dtn);           //使用duration构造,就是距离时间戳的时间长度

(2)时间点有个重要的函数:duration time_since_epoch()  (用于获取当前时间点距离时间戳的时间长度)

即经常用来得到当前时间点到1970年1月1日00:00的时间距离、该函数返回的duration的精度和构造time_point的时钟(Clock)有关(见4时钟详解)。

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include <chrono>
  3. #include <ctime>
  4. using namespace std;
  5. int main()
  6. {
  7. //距离时间戳2两秒
  8. chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(2));
  9. cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
  10. //转化为ctime,打印输出时间点
  11. time_t tt = chrono::system_clock::to_time_t(tp);
  12. char a[50];
  13. ctime_s(a, sizeof(a), &tt);
  14. cout << a;
  15. system("pause");
  16. return 0;
  17. }
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
int main()
{
//距离时间戳2两秒
chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(2));
cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
//转化为ctime,打印输出时间点
time_t tt = chrono::system_clock::to_time_t(tp);
char a[50];
ctime_s(a, sizeof(a), &tt);
cout << a;
system("pause");
return 0;
}


可以看出,时间戳就是使用的Unix的时间戳。

4.时钟:(代表当前系统的时间)

chrono中有三种时钟:system_clock,steady_clock和high_resolution_clock。每一个clock类中都有确定的time_point, duration, Rep, Period类型。

system_clock是不稳定的。因为时钟是可调的,即这种是完全自动适应本地账户的调节。这种调节可能造成的是,首次调用now()返回的时间要早于上次调用now()所返回的时间,这就违反了节拍频率的均匀分布。稳定闹钟对于超时的计算很重要,所以C++标准库提供一个稳定时钟 std::chrono::steady_clock。std::chrono::high_resolution_clock 是标准库中提供的具有最小节拍周期(因此具有最高的精度的时钟)。

上文所说time_since_epoch(),以及将要介绍的now()函数的返回值都依赖于时钟的精度,测试时钟的精度的一种方法就是:

[cpp] view plaincopyprint?
  1. <SPAN style="FONT-SIZE: 18px">#include <iostream>
  2. #include <chrono>
  3. using namespace std;
  4. int main()
  5. {
  6. cout << "system clock          : ";
  7. cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl;
  8. cout << "steady clock          : ";
  9. cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl;
  10. cout << "high resolution clock : ";
  11. cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl;
  12. system("pause");
  13. return 0;
  14. }</SPAN>
#include <iostream>
#include <chrono>
using namespace std;
int main()
{
cout << "system clock          : ";
cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl;
cout << "steady clock          : ";
cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl;
cout << "high resolution clock : ";
cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl;
system("pause");
return 0;
}

windows系统的测试结果是system_clock的精度是100纳秒,而high_resolution的精度是1纳秒,对于程序来说,一般毫秒级就够了,所以说chrono提供的时钟精度绰绰有余。

(1)成员函数static time_point now() noexcept; 用于获取系统的当前时间。

(2)由于各种time_point表示方式不同,chrono也提供了相应的转换函数 time_point_cast。

template <class ToDuration, class Clock, class Duration>
time_point<Clock,ToDuration> time_point_cast (const time_point<Clock,Duration>& tp);

传一个要转换为的精度的duration模板参数和一个要转换的time_point参数(用法见下面综合应用)

(3)其他成员函数:

to_time_t() time_point转换成time_t秒

from_time_t() 从time_t转换成time_point

综合应用:

输出当前时间,并且计算当前的时间距离1970年1月1日00:00的毫秒数

[cpp] view plaincopyprint?
  1. #include <iostream>
  2. #include <chrono>
  3. #include <ctime>
  4. using namespace std;
  5. int main()
  6. {
  7. //定义毫秒级别的时钟类型
  8. typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type;
  9. //获取当前时间点,windows system_clock是100纳秒级别的(不同系统不一样,自己按照介绍的方法测试),所以要转换
  10. microClock_type tp = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
  11. //转换为ctime.用于打印显示时间
  12. time_t tt = chrono::system_clock::to_time_t(tp);
  13. char _time[50];
  14. ctime_s(_time,sizeof(_time),&tt);
  15. cout << "now time is : " << _time;
  16. //计算距离1970-1-1,00:00的时间长度,因为当前时间点定义的精度为毫秒,所以输出的是毫秒
  17. cout << "to 1970-1-1,00:00  " << tp.time_since_epoch().count() << "ms" << endl;
  18. system("pause");
  19. return 0;
  20. }
#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
int main()
{
//定义毫秒级别的时钟类型
typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> microClock_type;
//获取当前时间点,windows system_clock是100纳秒级别的(不同系统不一样,自己按照介绍的方法测试),所以要转换
microClock_type tp = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
//转换为ctime.用于打印显示时间
time_t tt = chrono::system_clock::to_time_t(tp);
char _time[50];
ctime_s(_time,sizeof(_time),&tt);
cout << "now time is : " << _time;
//计算距离1970-1-1,00:00的时间长度,因为当前时间点定义的精度为毫秒,所以输出的是毫秒
cout << "to 1970-1-1,00:00  " << tp.time_since_epoch().count() << "ms" << endl;
system("pause");
return 0;
}

通过两张图片对比,时间点上相差48-34=14秒、、下面的一长串数字,切掉3位(毫秒)、是28-14=14秒、、正确!说明这一串数字的最后三位就是毫秒数、、充分说明了达到了毫秒级别。

将上面的程序中millisconds换成microseconds或者更小的单位,便可达到微妙,甚至更高的精度。

c++11 chrono全面解析(最高可达纳秒级别的精度)相关推荐

  1. linux 多个定时器,timer: 一个Linux下的超级精简的多重定时器:可实现成千上万个定时任务,定时精度可达纳秒级别,且同一时间点可添加不同的任务!适用于云后台服务和嵌入式等各种环境。...

    MT_Timer(MT译为Multiple或Multi) 一.介绍 一个Linux下的超级简洁的定时器:利用epoll机制和timerfd新特性实现的多重.多用.多个定时任务实现.只需要使用TIMER ...

  2. java格式化时间到微秒_Java日期解析具有微秒或纳秒精度

    TL;博士 LocalDateTime.parse( // With resolution of nanoseconds, represent the idea of a date and time ...

  3. 利用chrono统计毫秒,微妙,纳秒运行时间

    void CalRunTime() {auto t1=std::chrono::steady_clock::now();//run codeauto t2=std::chrono::steady_cl ...

  4. linux英伟达显卡内核不匹配,硬核观察|Linus 破例在 Linux 5.11 内核中允许英伟达显卡驱动加塞...

    Linus 破例在 Linux 5.11 内核中允许英伟达显卡驱动加塞 据 cnbeta 报道,曾因闭源驱动对英伟达爆粗口的 Linus Torvalds,刚刚宣布了 Linux 5.11 内核版本的 ...

  5. 从零开始研发GPS接收机连载——11、电文解析

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 从零开始研发GPS接收机连载--11.电文解析 前言 导航电文的格式 遥测字 交接字 第一块数据块 第二数据块 第三数据块 后记 前言 ...

  6. linux英伟达显卡内核不匹配,Linux 5.11内核将支持英伟达RTX 30系显卡

    原标题:Linux 5.11内核将支持英伟达RTX 30系显卡 在本周末Linux 5.11-c4版本发布前,Linus Torvalds将来自Nouveau driver的RTX 30系列显卡开源驱 ...

  7. C++ 11 chrono

    chrono 目录 chrono Abstract duration Abstract How Demo time_point Abstract How Demo Clock Abstract How ...

  8. C++11 chrono 库

    C++11 chrono 图解 1 设计一个时间日期库需要哪些要素 1.1 时间的计量形式 1.2 时间的计量精度 1.3 时间点 2 chrono库类 2.1 三种时钟 2.2 多种精度 2.3 时 ...

  9. C++11: chrono

    2019独角兽企业重金招聘Python工程师标准>>> chrono是一个time-library,要使用chrono这个库需要#include<chrono>. 通常要 ...

最新文章

  1. matlab pdist函数用法,pdist用法
  2. python项目实例初学者-python 初学者必备14张思维导图
  3. linux pci扫描链表,Linux Kernel ---- PCI Driver 分析
  4. 什么是Ajax和JSON,它们的优缺点
  5. 单例模式的5种实现方法及优缺点
  6. sublime设置自己的快捷键
  7. 订单状态 css_CSS状态2019
  8. Linux实现免密码登录
  9. MySQL-事务的实现-redo
  10. 清除SQLServer日志
  11. 蓝桥杯 ADV-184 算法提高 素数求和
  12. 华为交换机导入配置_华为交换机配置文件导入 华为s5700交换机配置教程
  13. 学计算机的学数学建模课吗,为什么数学建模与数学实验会进入大学课堂
  14. python矩阵乘法代码_python3 单行代码实现矩阵相乘
  15. BGP 自动路由聚合
  16. VsCode+PHP开发 推荐插件
  17. 出现Cannot find module 'xxx' 错误
  18. C++大法:举世闻名之BOOST大法精华浅析(三)内存管理库(小白piao分享)
  19. 模拟器什么的都过时了!这样玩吃鸡才能真正的高清无延迟
  20. excel三种查重方法

热门文章

  1. 网络编程 WSAStartup返回值介绍
  2. 理解SetCapture、ReleaseCapture、GetCapture
  3. 计算机教师个人能力不足,新教师工作中的不足之处总结
  4. EMC实验中RE理论干扰源的详细分析
  5. GitHub宣布已将所有代码永久封存于北极地底1000年!网友炸锅了:我写的bug终于能流传永世了!
  6. 计算机军中绿花谱子,军中绿花电子琴曲谱
  7. 运筹学——对偶单纯形法
  8. 双网卡绑定-bond
  9. 2011.3.12 (ULE)
  10. Run-Time Check Failure #0 - 错误问题