C++中Boost.Chrono时间库的使用方法
发布时间 - 2026-01-11 03:07:32 点击率:次前言

大家应该都有所体会,时钟这个东西在程序中扮演者重要的角色,在系统编程的时候睡眠、带超时的等待、带超时的条件变量、带超时的锁都会用到,但是往往对特定系统依赖性很大,感觉即使不考虑系统的跨平台性,如果能使用一个稳定的接口,同时如果能够方便的对时刻、时段等进行相关的操作和运算,将是再好不过的了。
在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_clock、boost::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::nanoseconds、chrono::milliseconds、chrono::microseconds、chrono::seconds、chrono::minutes、chrono::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
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# boost
# chrono使用
# chrono
# boost库的使用
# C++ 时间库duration 类的原理与复现(最新整理)
# C/C++时间库chrono的使用总结
# C++中std::chrono时间库的全面解析
# C/C++中时间库函数的使用详解
# C++11中的时间库std::chrono(引发关于时间的思考)
# c++11 Chrono时间库的使用小结
# 时长
# 六种
# 有人用
# 可以通过
# 自定义
# 来实现
# 库中
# 的是
# 都是
# 都有
# 权宜之计
# 第一个
# 也就
# 特点是
# 两种
# 可以用
# 依赖于
# 我们可以
# 这就
# 这两个
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何自定义分页视图?(Pagination示例)
Claude怎样写结构化提示词_Claude结构化提示词写法【教程】
HTML 中动态设置元素 name 属性的正确语法详解
Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】
JavaScript中的标签模板是什么_它如何扩展字符串功能
html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】
昵图网官网入口 昵图网素材平台官方入口
java获取注册ip实例
Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】
html5源代码发行怎么设置权限_访问权限控制方法与实践【指南】
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
免费视频制作网站,更新又快又好的免费电影网站?
如何在景安服务器上快速搭建个人网站?
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
音响网站制作视频教程,隆霸音响官方网站?
详解Oracle修改字段类型方法总结
js代码实现下拉菜单【推荐】
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
如何在宝塔面板中修改默认建站目录?
node.js报错:Cannot find module 'ejs'的解决办法
Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】
开心动漫网站制作软件下载,十分开心动画为何停播?
如何用西部建站助手快速创建专业网站?
网站建设要注意的标准 促进网站用户好感度!
Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
php结合redis实现高并发下的抢购、秒杀功能的实例
大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?
如何在宝塔面板创建新站点?
如何在云虚拟主机上快速搭建个人网站?
JavaScript Ajax实现异步通信
浅析上传头像示例及其注意事项
Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
如何在Windows 2008云服务器安全搭建网站?
教你用AI将一段旋律扩展成一首完整的曲子
iOS验证手机号的正则表达式
ChatGPT 4.0官网入口地址 ChatGPT在线体验官网
弹幕视频网站制作教程下载,弹幕视频网站是什么意思?
Bootstrap整体框架之CSS12栅格系统
如何实现建站之星域名转发设置?
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
高防服务器租用如何选择配置与防御等级?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
javascript读取文本节点方法小结
Laravel的.env文件有什么用_Laravel环境变量配置与管理详解
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Laravel API路由如何设计_Laravel构建RESTful API的路由最佳实践
Laravel Asset编译怎么配置_Laravel Vite前端构建工具使用
下一篇:银行网银安全性分析
下一篇:银行网银安全性分析

