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

   2023-02-09 学习力0
核心提示:目录一、Boost.Chrono说明二、示例代码一、Boost.Chrono说明库 Boost.Chrono 提供了多种时钟。例如,您可以获取当前时间,也可以测量流程中经过的时间。Boost.Chrono 的部分内容已添加到 C++11。如果您的开发环境支持 C++11,您可以访问头文件 chrono.xml 中

一、Boost.Chrono说明

库 Boost.Chrono 提供了多种时钟。例如,您可以获取当前时间,也可以测量流程中经过的时间。

Boost.Chrono 的部分内容已添加到 C++11。如果您的开发环境支持 C++11,您可以访问头文件 chrono.xml 中定义的多个时钟。但是,C++11 不支持某些功能,例如用于测量 CPU 时间的时钟。此外,只有 Boost.Chrono 支持用户定义的时间输出格式。

二、示例代码

您可以通过头文件 boost/chrono.hpp 访问所有 Boost.Chrono 时钟。唯一的扩展是用户定义的格式,它需要头文件 boost/chrono_io.hpp。

例 37.1。来自 Boost.Chrono 的所有时钟

#include <boost/chrono.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  std::cout << system_clock::now() << '\n';
#ifdef BOOST_CHRONO_HAS_CLOCK_STEADY
  std::cout << steady_clock::now() << '\n';
#endif
  std::cout << high_resolution_clock::now() << '\n';
#ifdef BOOST_CHRONO_HAS_PROCESS_CLOCKS
  std::cout << process_real_cpu_clock::now() << '\n';
  std::cout << process_user_cpu_clock::now() << '\n';
  std::cout << process_system_cpu_clock::now() << '\n';
  std::cout << process_cpu_clock::now() << '\n';
#endif
#ifdef BOOST_CHRONO_HAS_THREAD_CLOCK
  std::cout << thread_clock::now() << '\n';
#endif
}

Example37.1

例 37.1 介绍了 Boost.Chrono 提供的所有时钟。所有时钟都有一个共同的成员函数 now(),它返回一个时间点。所有时间点都相对于普遍有效的时间点。这个参考时间点称为纪 元。一个经常使用的纪 元是 1970 年 1 月 1 日。示例 37.1 为显示的每个时间点写入纪 元。

Boost.Chrono 包括以下时钟:

boost::chrono::system_clock 返回系统时间。这是通常显示在计算机桌面上的时间。如果您更改计算机上的时间,boost::chrono::system_clock 会返回新时间。示例 37.1 将字符串写入标准输出,如下所示:自 1970 年 1 月 1 日以来的 13919594042183544 [1/10000000] 秒。

对于 boost::chrono::system_clock,epoch 没有标准化。这些示例中使用的纪 元 1970 年 1 月 1 日取决于实现。但是,如果您特别想获取自 1970 年 1 月 1 日以来的时间,请调用 to_time_t()。 to_time_t() 是一个静态成员函数,它以 std::time_t 形式返回自 1970 年 1 月 1 日以来的当前系统时间秒数。

boost::chrono::steady_clock 是一个时钟,它总是在稍后访问时返回。即使在计算机上设置了时间, boost::chrono::steady_clock 也会返回稍后的时间。这个时间被称为单调时间。

示例 37.1 显示自系统启动以来的纳秒数。该消息如下所示:自启动以来 10594369282958 纳秒。 boost::chrono::steady_clock 测量自上次启动以来经过的时间。但是,自上次启动后开始测量是一个实现细节。参考点可能会随着不同的实现而改变。

并非所有平台都支持 boost::chrono::steady_clock。只有定义了宏 BOOST_CHRONO_HAS_CLOCK_STEADY 时,时钟才可用。

boost::chrono::high_resolution_clock 是 boost::chrono::system_clock 或 boost::chrono::steady_clock 的类型定义,具体取决于哪个时钟更精确地测量时间。因此,输出与 boost::chrono::high_resolution_clock 所基于的时钟的输出相同。

boost::chrono::process_real_cpu_clock 返回进程运行的 CPU 时间。时钟测量程序启动后的时间。示例 37.1 将一个字符串写入标准输出,如下所示:自进程启动以来的 1000000 纳秒。

您也可以使用 ctime 中的 std::clock() 获得这个时间。事实上,目前 boost::chrono::process_real_cpu_clock 的实现是基于 std::clock() 的。

只有定义了宏 BOOST_CHRONO_HAS_PROCESS_CLOCKS 才能使用 boost::chrono::process_real_cpu_clock 时钟和其他测量 CPU 时间的时钟。

boost::chrono::process_user_cpu_clock 返回进程在用户空间中花费的 CPU 时间。用户空间是指与操作系统功能分开运行的代码。在程序调用的操作系统函数中执行代码所花费的时间不计入用户空间时间。

boost::chrono::process_user_cpu_clock 只返回在用户空间运行的时间。如果程序暂停了一段时间,例如通过 Windows Sleep() 函数,则在 Sleep() 中花费的时间不会由 boost::chrono::process_user_cpu_clock 测量。

示例 37.1 将一个字符串写入标准输出,如下所示:自进程启动以来的 15600100 纳秒。

boost::chrono::process_system_cpu_clock 类似于 boost::chrono::process_user_cpu_clock。然而,这个时钟测量在内核空间中花费的时间。 boost::chrono::process_system_cpu_clock 返回进程执行操作系统函数所花费的 CPU 时间。

示例 37.1 将一个字符串写入标准输出,如下所示: 自进程启动后 0 纳秒。因为这个例子没有直接调用操作系统函数并且因为 Boost.Chrono 只使用了几个操作系统函数,所以 boost::chrono::process_system_cpu_clock 可能返回 0。

boost::chrono::process_cpu_clock 返回一个元组,其中包含 boost::chrono::process_real_cpu_clock、boost::chrono::process_user_cpu_clock 和 boost::chrono::process_system_cpu_clock 返回的 CPU 时间。示例 37.1 将字符串写入标准输出,如下所示:{1000000;15600100;0} 自进程启动后的纳秒。

boost::chrono::thread_clock 返回线程使用的时间。 boost::chrono::thread_clock 测量的时间与 CPU 时间相当,除了它是每个线程而不是每个进程。 boost::chrono::thread_clock 返回线程运行的 CPU 时间。它不区分在用户空间和内核空间中花费的时间。

并非所有平台都支持 boost::chrono::thread_clock。如果定义了宏 BOOST_CHRONO_HAS_THREAD_CLOCK,则只能使用 boost::chrono::thread_clock。

Boost.Chrono 提供宏 BOOST_CHRONO_THREAD_CLOCK_IS_STEADY 来检测 boost::chrono::thread_clock 是否像 boost::chrono::steady_clock 一样测量单调时间。

示例 37.1 将字符串写入标准输出,如下所示:自线程启动以来的 15600100 纳秒。

Boost.Chrono 中的所有时钟都依赖于操作系统功能;因此,操作系统决定了返回时间的精确度和可靠性。

例 37.2。使用 Boost.Chrono 增加和减少持续时间

#include <boost/chrono.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  process_real_cpu_clock::time_point p = process_real_cpu_clock::now();
  std::cout << p << '\n';
  std::cout << p - nanoseconds{1} << '\n';
  std::cout << p + milliseconds{1} << '\n';
  std::cout << p + seconds{1} << '\n';
  std::cout << p + minutes{1} << '\n';
  std::cout << p + hours{1} << '\n';
}

now() 为所有时钟返回 boost::chrono::time_point 类型的对象。这种类型与时钟紧密耦合,因为时间点是相对于由时钟定义的参考时间点测量的。 boost::chrono::time_point 是一个模板,它需要时钟的类型作为参数。每种时钟类型都为其专门的 boost::chrono::time_point 提供类型定义。例如,process_real_cpu_clock 的类型定义是 process_real_cpu_clock::time_point。

Boost.Chrono 还提供了类 boost::chrono::duration,它描述了持续时间。因为 boost::chrono::duration 也是一个模板,所以 Boost.Chrono 提供了六个类 boost::chrono::nanoseconds, boost::chrono::milliseconds, boost::chrono::microseconds, boost::chrono::秒、boost::chrono::minutes 和 boost::chrono::hours,它们更易于使用。

Boost.Chrono 重载了几个运算符来处理时间点和持续时间。示例 37.2 从 p 中减去持续时间或将持续时间添加到 p 以获得新的时间点,这些时间点将写入标准输出。

示例 37.2 以纳秒为单位显示所有时间点。 Boost.Chrono 在处理时间点和持续时间时自动使用最小单位,以确保结果尽可能精确。如果您想将时间点与另一个单元一起使用,则必须对其进行投射。

例 37.3。使用 boost::chrono::time_point_cast() 投射时间点

#include <boost/chrono.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  process_real_cpu_clock::time_point p = process_real_cpu_clock::now();
  std::cout << p << '\n';
  std::cout << time_point_cast<minutes>(p) << '\n';
}

boost::chrono::time_point_cast() 函数的使用类似于强制转换运算符。示例 37.3 使用 boost::chrono::time_point_cast() 将基于纳秒的时间点转换为以分钟为单位的时间点。在这种情况下,您必须使用 boost::chrono::time_point_cast() ,因为时间点不能以不太精确的单位(分钟)表示而不会丢失精度。您不需要 boost::chrono::time_point_cast() 从不太精确的单位转换为更精确的单位。

Boost.Chrono 还为持续时间提供强制转换运算符。

例 37.4。使用 boost::chrono::duration_cast() 投射持续时间

#include <boost/chrono.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  minutes m{1};
  seconds s{35};
  std::cout << m + s << '\n';
  std::cout << duration_cast<minutes>(m + s) << '\n';
}

Example37.4

示例 37.4 使用函数 boost::chrono::duration_cast() 将持续时间从秒转换为分钟。此示例将 1 分钟写入标准输出。

例 37.5。舍入持续时间

#include <boost/chrono.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  std::cout << floor<minutes>(minutes{1} + seconds{45}) << '\n';
  std::cout << round<minutes>(minutes{1} + seconds{15}) << '\n';
  std::cout << ceil<minutes>(minutes{1} + seconds{15}) << '\n';
}

Boost.Chrono 还提供了在施法时舍入持续时间的功能。 boost::chrono::round() 向上或向下舍入, boost::chrono::floor() 向下舍入, boost::chrono::ceil() 向上舍入。 boost::chrono::floor() 使用 boost::chrono::duration_cast() - 这两个函数之间没有区别。

示例 37.5 将 1 分钟、1 分钟和 2 分钟写入标准输出。

例 37.6。用于用户定义输出的流操纵器

#define BOOST_CHRONO_VERSION 2
#include <boost/chrono.hpp>
#include <boost/chrono/chrono_io.hpp>
#include <iostream>
using namespace boost::chrono;
int main()
{
  std::cout << symbol_format << minutes{10} << '\n';
  std::cout << time_fmt(boost::chrono::timezone::local, "%H:%M:%S") <<
    system_clock::now() << '\n';
}

Boost.Chrono 提供了各种流操纵器来格式化时间点和持续时间的输出。例如,使用操纵器 boost::chrono::symbol_format(),时间单位被写为符号而不是名称。因此,示例 37.6 显示 10 分钟。

操纵器 boost::chrono::time_fmt() 可用于设置时区和格式字符串。时区必须设置为 boost::chrono::timezone::local 或 boost::chrono::timezone::utc。格式字符串可以使用标志来引用时间点的各种组件。例如,示例 37.6 将一个字符串写入标准输出,如下所示:15:46:44。

除了流操纵器,Boost.Chrono 还为许多不同的定制提供了方面。例如,有一个方面可以以另一种语言输出时间点。

注意

自 Boost 1.52.0 以来有两个版本的输入/输出函数。从 Boost 1.55.0 开始,默认使用较新的版本。如果您使用早于 1.55.0 的版本,则必须定义宏 BOOST_CHRONO_VERSION 并将其设置为 2 才能使示例 37.6 正常工作。

原文地址:https://yamagota.blog.csdn.net/article/details/127701966
 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • Aurelius vs mORMot vs EntityDAC Delphi 的
    Aurelius vs mORMot vs EntityDAC   Delphi 的 ORM框架:http://www.tmssoftware.com/site/aurelius.asp#product-buy-onlinehttps://synopse.info/fossil/wiki/Synopse+OpenSourcehttps://www.devart.com/entitydac/download.htmlkbmMW  http://www.compo
    02-09
  • 【Ruby】Mac gem的一些坑
    前言自上一次升级MacOS系统后出现jekyll无法构建的问题,当时处理半天。谁知道最近又升级了MacOS,荒废博客多时,今天吝啬写了一篇准备发布,构建报错,问题重新。还是记录下,以防下次升级出问题。问题描述安装jekyll静态博客需要在Ruby环境下运行,于是参照
    02-09
  • iOS oc 调用 swift
    如股票oc要调用swift里面的代码 需要包含固定这个头文件项目名称 LiqunSwiftDemo-Swift.h         #ProjectName#-Swift.h固定的写法swift 目的 是取代oc 但是 不会完全取代 只是前端的替换LiqunSwiftDemo-Swift 点进去 可以看到 所有的swift代码 都产生
    02-09
  • objective-c NSTimer 定时器
    -(void)initTimer{//时间间隔NSTimeInterval timeInterval =3.0 ;//定时器repeats 表示是否需要重复,NO为只重复一次NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(mobileAnimation) userInfo:nil
    02-09
  • Objective-C  日记③ 字符串
    Objective-C 日记③ 字符串
    一、创建字符串、类方法   公式创建NSString  +(id) stringWithFormat:(NSString *) format,……;eg:  NSString *height;  height=[NSString stringWithFormat:@"高度是: %d 长度: %d",10,20];得到的字符串:“高度是: 10 长度: 20” 注意:  省
    02-09
  • Objective-C KVC机制
    Objective-C KVC机制http://blog.csdn.net/omegayy/article/details/7381301全部推翻重写一个版本,这是我在公司内做技术分享的文档总结,对结构、条理做了更清晰的调整。 1.    基本概念MODEL主要是英文文档里面经常出现的一些概念,讲解一下,方便英文
    02-09
  • objective-c 加号 减号 - +
    “加号代表static”是错误的说法,可能跟你那样表达的人其实意思是:“前置加号的方法相当于Java 里面的静态方法”。在Oc中,方法分为类方法和实例方法。前置加号(+)的方法为类方法,这类方法是可以直接用类名来调用的,它的作用主要是创建一个实例。有人把
    02-09
  • Objective-C  日记①
    Objective-C 日记①
    1、Xcode的.m扩展名表示文件含有Object-C代码,C以.c文件,C++以.cpp文件2、头文件声明:C使用:#include,O-C使用#import(当然你也可以使用#include) 3、输出方式:  C:printf("",参数);  O-C:NSLog(@"",参数); 4、布尔类型  C:bool 具有true
    02-09
  • ASP.NET MVC 操作AD 获取域服务器当前用户姓
    #region 根据当前登录域账号 获取AD用户姓名和所在OU目录/// summary/// 根据当前登录域账号 获取AD用户姓名和所在OU目录/// /summary/// param name="searchUser"要搜索的当前用户名/param/// param name="paths"out返回该用户所在OU目录/param/// param nam
    02-09
  • swift和OC - 拆分数组 和 拆分字符串
    1. 拆分数组 /// 根据 数组 截取 指定个数返回 多个数组的集合func splitArray( array: [Date], withSubSize subSize: Int) - [[Date]] {//数组将被拆分成指定长度数组的个数let count = array.count% subSize == 0 ? (array.count/ subSize) : (array.count
    02-08
点击排行