C++中Boost.Chrono时间库的使用方法

前言

大家应该都有所体会,时钟这个东西在程序中扮演者重要的角色,在系统编程的时候睡眠、带超时的等待、带超时的条件变量、带超时的锁都会用到,但是往往对特定系统依赖性很大,感觉即使不考虑系统的跨平台性,如果能使用一个稳定的接口,同时如果能够方便的对时刻、时段等进行相关的操作和运算,将是再好不过的了。

在boost库中和时间相关的库有Boost.DateTime和Boost.Chrono,前者专注于时间时刻以及本地化相关的内容,而后者主要是时刻、时长和时间的计算等内容。当然,C++11标准已经支持std::chrono了,但是为了兼容老编译系统现在很多C++库和程序都使用boost.chrono作为时间类库(还有的原因就是std::chrono没有收录boost.chrono的所有功能,比如统计CPU使用时间、自定义时间输出格式等),不过比较可惜的是即便使用boost::chrono作为权宜之计,也需要boost-1.47版本之上才行,而现在比较旧的发行版需要升级boost库才可以使用。想想现在RHEL-6.x仍然被大规模的部署,而且RedHat要为这货提供长达十年的技术支持,真不知道啥时候才能顺顺利利的享受C++11……

Boost.Chrono的时间类型分为duration和time_point,也就是时长和时刻两类,很多概念和接口都是围绕这两个维度去定义和实现的。

一、Clock

clock是Boost.Chrono中的重要概念,而且这些clock都包含一个now()的成员函数,用于返回当前的time_point。Boost.Chrono包含的clock类型有:

  (1) chrono::system_clock 代表系统时间,比如电脑上显示的当前时间,其特点是这个时间可以被用户手动设置更新,所以这个时钟是可以和外部时钟源同步的。这个时钟还有一个to_time_t()成员函数,用于返回自1970.1.1开始到某个时间点所经过的秒数,数据类型是std::time_t。这种时钟通常用来转换成日历时间使用。

  (2) chrono::steady_clock 其特点是时间是单调增长的,后一个时刻访问得到的时间点肯定比之前时刻得到的时间点要晚,即使我们手动将系统时间向前调整了也不会改变这个时钟稳步向前推行累计,其也被称为monotonic time,该时钟是均匀增长且不能被调整,其特性对于很多不允许时间错乱的系统是十分重要的。chrono::steady_clock通常是基于系统启动时间来计时的,而且常常用来进行耗时、等待等工作使用。

  (3) chrono::high_resolution_clock 依赖于系统实现,通常是上面两种时钟的某个宏定义,取决于哪个时钟源更为的精确,所以其输出也决定于取决于上面哪个clock来实现的。

  (4) chrono::process_real_cpu_clock 表示自进程启动以来使用的CPU时间,而这个数据也可以通过使用std::clock()来获得。chrono::process_user_cpu_clockboost::chrono::process_system_cpu_clock表示自进程启动以来,在用户态、内核态所花费的时间,而所有的这些事件可以通过chrono::process_cpu_clock来获得,他返回上面所有时间组成的一个tuple结构。

  (5) chrono::thread_clock 返回基于线程统计的花费时间,而且不区分用户态、内核态的时间。

二、time_point

time_point代表时间点,其等价于某个时刻(clock)+duration的结果,同时两个time_point做减法也可以得到一个duration。time_point常见的描述为:3分钟之后、2038年1月1日10:32:23、定时器启动后的20ms……

上面的clock都有一个now()成员函数,其返回的就是chrono::time_point类型。这个类型使用一个模板来实现的,所以其实际类型极度依赖于所选择的时钟源。

Boost.Chrono有一个chrono::time_point_cast转换函数,可以显式从高粒度向低粒度对time_point进行转换。

chrono::process_real_cpu_clock::time_point p = chrono::process_real_cpu_clock::now();
std::cout << chrono::time_point_cast<minutes>(p) << '\n';

三、duration

关于时长,chrono::duration也是一个模板类型,其第一个模板参数表明存储所用的数据类型(int、long、double等),第二个模板参数表示ratio(比如24、60、1000等)。为了方便用户的使用,Boost.Chrono提供了duration常用的六种时间类型,且他们都用一个足够大的整数进行内部保存,其计量值可以用count()成员函数得到:

chrono::nanosecondschrono::millisecondschrono::microsecondschrono::secondschrono::minuteschrono::hours,而且为这些类型都重载了计算操作符:+、-、<等,方便时间的计算和比较。文档说传统的Boost.DateTime是用继承实现的,相比而言Boost.Chrono更加的简洁高效,而且和前者保持了一致的接口。

chrono::steady_clock::time_point start = chrono::steady_clock::now();
...
chrono::duration<double> sec = chrono::steady_clock::now() - start;
std::cout << "we took " << sec.count() << " seconds\n";
auto go = chrono::steady_clock::now() + chrono::nanoseconds(500);
while (chrono::steady_clock::now() < go)
... ;

上面的六种time_point类型表示的维度不一,粗粒度的时长肯定能用细粒度的类型表示,反之则可能丢失精度,所以需要使用chrono::duration_cast()函数做显式的转换。

可能上面六种类型的时间不咋的,但重点是现在boost::chrono被广为使用在boost的其他库里面,比如我们看一个条件变量的带超时等待的原型:

template< typename Clock, typename Duration >
cv_status wait_until( std::unique_lock< mutex > & lk,
      std::chrono::time_point< Clock, Duration > const& abs_time);

template< typename Rep, typename Period >
cv_status wait_for( std::unique_lock< mutex > & lk,
     std::chrono::duration< Rep, Period > const& rel_time);

这就意味着我们可以直接将chrono::minutes{2}这样的duration对象丢给这个函数就好了,创建任意精度的时长都很方便,而不用像以前一样关注函数接口有人用seconds、有人用milliseconds、有人用timeval了。

现在boost库和标准库中,基于时间段超时的函数都具有for后缀,而基于时间点超时的变量具有until后缀,比如this_thread::sleep_for()this_thread::sleep_until()类似的还有:wait、try_lock、unique_lock用于条件变量、mutex互斥、unique_lock操作。

四、自定义格式的时间输出

通过time_fmt()可以对时刻进行格式化输出,使用的时候需要包含头文件。

time_fmt(boost::chrono::timezone::local, "%H:%M:%S");
time_fmt(boost::chrono::timezone::utc, "%H:%M:%S");

参考

Chapter 37. Boost.Chrono

Chapter 8. Boost.Chrono 2.0.5

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • C++中Boost.Chrono时间库的使用方法

    前言 大家应该都有所体会,时钟这个东西在程序中扮演者重要的角色,在系统编程的时候睡眠.带超时的等待.带超时的条件变量.带超时的锁都会用到,但是往往对特定系统依赖性很大,感觉即使不考虑系统的跨平台性,如果能使用一个稳定的接口,同时如果能够方便的对时刻.时段等进行相关的操作和运算,将是再好不过的了. 在boost库中和时间相关的库有Boost.DateTime和Boost.Chrono,前者专注于时间时刻以及本地化相关的内容,而后者主要是时刻.时长和时间的计算等内容.当然,C++11标准已经支持st

  • C++ 中boost::share_ptr智能指针的使用方法

    C++ 中boost::share_ptr智能指针的使用方法 最近项目中使用boost库的智能指针,感觉智能指针还是蛮强大的,在此贴出自己学习过程中编写的测试代码,以供其他想了解boost智能指针的朋友参考,有讲得不正确之处欢迎指出讨论.当然,使用boost智能指针首先要编译boost库,具体方法可以网上查询,在此不再赘述. 智能指针能够使C++的开发简单化,主要是它能够自动管理内存的释放,而且能够做更多的事情,即使用智能指针,则可以再代码中new了之后不用delete,智能指针自己会帮助你管理

  • python中日期和时间格式化输出的方法小结

    本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一个参数的使用方法及范例. 下面是格式化日期和时间时可用的替换符号 %a 输出当前是星期几的英文简写 >>> import datetime >&

  • 利用boost获取时间并格式化的方法

    利用boost来获取当前时间又方便快捷,还不用考虑跨平台的问题. 1.   输出YYYYMMDD #include <boost/date_time/gregorian/gregorian.hpp> #define BOOST_DATE_TIME_SOURCE std::string strTime = boost::gregorian::to_iso_string(\ boost::gregorian::day_clock::local_day()); std::cout <<

  • Python中三种时间格式转换的方法

    目录 一 时间元组 二 字符串与时间戳 三 时间的加减用法 一 时间元组 1. 时间元组和时间戳的互化 import time,datetime # 获取当前时间的时间元组 t = time.localtime() print(t) # 时间元组转时间戳 timestamp = time.mktime(t) print(timestamp) # time.struct_time(tm_year=2019, tm_mon=10, tm_mday=23, tm_hour=23, tm_min=15,

  • 浅析C++中boost.variant的几种访问方法

    Boost.Variant Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象.这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题. Variant 库如何改进你的程序? •对用户指定的多种类型的进行类型安全的存储和取回 •在标准库容器中存储不同类型的方法 •变量访问的编译期检查 •高效的.基于栈的变量存储 Variant 库关注的是对一组限定类型的类型安全存储及取回,即非无类的联合.Boost.Variant 库与 Boost.

  • PowerShell中按修改时间查找文件的方法

    本文介绍一个PowerShell中按文件的的修改时间来查找文件,这里要用到文件对象的LastWriteTime这个属性. 在很多时候,我都都需要按修改时间来查找文件.比如一个网站,近期发现被人挂马了,我们可能会看看近期的备份是否有被修改,从而确定一下被黑的大致时间段.有了这个时间段后,我们要看看这段时间之内有哪些文件被修改过,有哪些新增上来的文件,很有可能黑客留下下的一句话木马,甚至大马就在里面. 下面我们来看看PowerShell中如何根据文件修改时间来查找文件. 小编先来看看d盘根目录下有些

  • C++ Boost Chrono实现计时码表流程详解

    目录 一.Boost.Chrono说明 二.示例代码 一.Boost.Chrono说明 库 Boost.Chrono 提供了多种时钟.例如,您可以获取当前时间,也可以测量流程中经过的时间. Boost.Chrono 的部分内容已添加到 C++11.如果您的开发环境支持 C++11,您可以访问头文件 chrono.xml 中定义的多个时钟.但是,C++11 不支持某些功能,例如用于测量 CPU 时间的时钟.此外,只有 Boost.Chrono 支持用户定义的时间输出格式. 二.示例代码 您可以通过

  • C++11中的时间库std::chrono(引发关于时间的思考)

    前言 时间是宝贵的,我们无时无刻不在和时间打交道,这个任务明天下班前截止,你点的外卖还有5分钟才能送到,那个程序已经运行了整整48个小时,既然时间和我们联系这么紧密,我们总要定义一些术语来描述它,像前面说到的明天下班前.5分钟.48个小时都是对时间的描述,程序代码构建的程序世界也需要定义一些术语来描述时间. 今天要总结学习的是 std::chrono 库,它是 C++11 标准时从 boost 库中引入的,其实在 C++ 中还有一种 C 语言风格的时间管理体系,像我们常见的函数 time().c

  • C++11中的chrono库详解

    目录 前言 1.记录时长的duration 2.表示时间点的time_point 3.获取系统时钟的clocks 前言 C++11提供了日期时间相关的库chrono,通过chrono库可以很方便的处理日期和时间.chrono库主要包含3种类型:时间间隔duration.时钟clocks和时间点time_point 1.记录时长的duration duration为一个模板类,表示时间间隔,可以是几秒.几分钟或者几个小时的时间间隔.duration的原型如下: template <class Re

随机推荐