C++11计时器之chrono库简介

 更新时间:2023年12月14日 10:36:34   作者:森明帮大于黑虎帮  
C++11有了chrono库,可以在不同系统中很容易的实现定时功能,要使用chrono库,需要#include,其所有实现均在std::chrono namespace下,本文给大家介绍C++11计时器:chrono库介绍,感兴趣的朋友一起看看吧

C++11计时器:chrono库介绍

C++11有了chrono库,可以在不同系统中很容易的实现定时功能。

要使用chrono库,需要#include,其所有实现均在std::chrono namespace下。注意标准库里面的每个命名空间代表了一个独立的概念。

chrono是一个模版库,使用简单,功能强大,只需要理解三个概念:duration、time_point、clock

一 、时钟-CLOCK

chrono库定义了三种不同的时钟:

 std::chrono::system_clock:  依据系统的当前时间 (不稳定)
 std::chrono::steady_clock:  以统一的速率运行(不能被调整)
 std::chrono::high_resolution_clock: 提供最高精度的计时周期(可能是steady_clock或者system_clock的typedef)

二、这三个时钟有什么区别呢?

system_clock就类似Windows系统右下角那个时钟,是系统时间。明显那个时钟是可以乱设置的。明明是早上10点,却可以设置成下午3点。

steady_clock则针对system_clock可以随意设置这个缺陷而提出来的,他表示时钟是不能设置的。

high_resolution_clock则是一个高分辨率时钟。

这三个时钟类都提供了一个静态成员函数now()用于获取当前时间,该函数的返回值是一个time_point类型,

system_clock除了now()函数外,还提供了to_time_t()静态成员函数。用于将系统时间转换成熟悉的std::time_t类型,得到了time_t类型的值,在使用ctime()函数将时间转换成字符串格式,就可以很方便地打印当前时间了。

#include<iostream>
#include<vector>
#include<string>
#include<ctime>//将时间格式的数据转换成字符串
#include<chrono>
using namespace std::chrono;
using namespace std;
int main()
{
    //获取系统的当前时间
    auto t = system_clock::now();
    //将获取的时间转换成time_t类型
    auto tNow = system_clock::to_time_t(t);
    //ctime()函数将time_t类型的时间转化成字符串格式,这个字符串自带换行符
    string str_time = std::ctime(&tNow);
    cout<<str_time;
    return 0;
}

三、持续的时间 - duration

td::chrono::duration<int,ratio<60,1>> ,表示持续的一段时间,这段时间的单位是由ratio<60,1>决定的,int表示这段时间的值的类型,函数返回的类型还是一个时间段duration

std::chrono::duration<double,ratio<60,1>>

由于各种时间段(duration)表示不同,chrono库提供了duration_cast类型转换函数。

duration_cast用于将duration进行转换成另一个类型的duration。

duration还有一个成员函数count(),用来表示这一段时间的长度

#include<iostream>
#include<string.h>
#include<chrono>
using namespace std::chrono;
using namespace std;
int main()
{
    auto start = std::chrono::steady_clock::now();
    for(int i=0;i<100;i++)
        cout<<"nice"<<endl;
    auto end = std::chrono::steady_clock::now();
    auto tt = std::chrono::duration_cast<microseconds>(end - start);
    cout<<"程序用时="<<tt.count()<<"微秒"<<endl;
    return 0;
}

四、时间点 - time_point

std::chrono::time_point 表示一个具体时间,如上个世纪80年代、你的生日、今天下午、火车出发时间等,只要它能用计算机时钟表示。鉴于我们使用时间的情景不同,这个time point具体到什么程度,由选用的单位决定。一个time point必须有一个clock计时

设置一个时间点:

std::time_point<clock类型> 时间点名字

//设置一个高精度时间点
    std::time_point<high_resolution_clock> high_resolution_clock::now();
//设置系统时钟
	std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();

另一个实例:

#define _CRT_SECURE_NO_WARNINGS //localtime()需要这个宏
#include<iostream>
#include<chrono>
#include<vector>
#include<string>
#include<algorithm>
//#include<stdio.h>
#include<iomanip> //put_time需要的头文件
#include<sstream>
    // template <class _Rep>
    // struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type
    // template <class _Rep>
    // _INLINE_VAR constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value;
    // // STRUCT TEMPLATE duration_values
    // template <class _Rep>
    // struct duration_values { // gets arithmetic properties of a type
    //     _NODISCARD static constexpr _Rep zero() noexcept {
    //         // get zero value
    //         return _Rep(0);
    //     }
    //     _NODISCARD static constexpr _Rep(min)() noexcept {
    //         // get smallest value
    //         return numeric_limits<_Rep>::lowest();
    //     }
    //     _NODISCARD static constexpr _Rep(max)() noexcept {
    //         // get largest value
    //         return (numeric_limits<_Rep>::max)();
    //     }
    // };
//时间长度
void Func1(){
    //chrono重载了各种运算符
    std::chrono::hours             c1(1);                //1小时
    std::chrono::minutes           c2(60);               //60分钟
    std::chrono::seconds           c3(60*60);            //60*60s
    std::chrono::milliseconds      c4(60*60*1000);       //60*60*1000毫秒
    std::chrono::microseconds      c5(60*60*1000*1000);  //微秒 溢出
    std::chrono::nanoseconds       c6(60*1000*1000*1000);//纳秒 溢出
    if(c1==c2){
        std::cout<<"c1==c2"<<std::endl;
    }
    if(c1==c3){
        std::cout<<"c1==c3"<<std::endl;
    }
    if(c2==c3){
        std::cout<<"c2==c3"<<std::endl;
    }
    //获取时钟周期的值,返回的是int整数
    std::cout<<"c1= "<<c1.count()<<std::endl;
    std::cout<<"c2= "<<c2.count()<<std::endl;
    std::cout<<"c3= "<<c3.count()<<std::endl;
    std::cout<<"c4= "<<c4.count()<<std::endl;
    std::chrono::seconds             c7(1);               //1秒
    std::chrono::milliseconds        c8(1*1000);          //1000毫秒;1s
    std::chrono::microseconds        c9(1*1000*1000);     //1000*1000微秒 1s
    std::chrono::nanoseconds         c10(1*1000*1000*1000);//1000*1000*1000纳秒 1s;
    std::cout<<c7.count()<<std::endl;
    std::cout<<c8.count()<<std::endl;
    std::cout<<c9.count()<<std::endl;
    std::cout<<c10.count()<<std::endl;
}
//系统时间
/**
 * @brief 
 * 
 * system_clock 类支持了对系统时钟的访问, 提供了三个静态成员函数:
返回当前时间的时间点。
static std::chrono::time_point<std::chrono::system_clock> now() noexcept;
将时间点 time_point 类型转换为 std::time_t 类型。
static std::time_t to_time_t( const time_point& t ) noexcept;
将 std::time_t 类型转换为时间点 time_point 类型。
static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept;
 */
void Func2(){
    //静态成员函数 static std::chrono::time_point<std::chrono::system_clock> now() noexcept
    //这些都可以简写用auto now=std::chrono::system_clock()::now()接收
    //1、静态成员函数 static std::chrono::system_clock::now()用来获取系统时间,C++时间
    std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
    //2、静态成员函数 static std::chrono::system_clock::to_time_t()把C++系统时间转换为time_t (utc时间)
    time_t t_now=std::chrono::system_clock::to_time_t(now);
    //3、std::localtime()函数把time_t时间转换为本地时间(北京时间)
    // std::localtime()不是线程安全的,VS用localtime_t()代替,linux用local_time_r()代替
    //tm结构体
    tm* tm_now=localtime(&t_now);
    //格式化输出tm结构体中的成员
    std::cout<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S")<<std::endl;
    std::cout<<std::put_time(tm_now,"%Y-%m-%d")<<std::endl;
    std::cout<<std::put_time(tm_now,"%H:%M:%S")<<std::endl;
    //但是通常C++一般不打印出时间,而是把时间存储到一个字符串中
    std::stringstream ss;  //创建stringstream对象 ss,需要包含<sstream>头文件
    ss<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S");
    std::string time_str=ss.str();
    std::cout<<time_str<<std::endl;
}   
// struct steady_clock { // wraps QueryPerformanceCounter
//         using rep                       = long long;
//         using period                    = nano;
//         using duration                  = nanoseconds;
//         using time_point                = chrono::time_point<steady_clock>;
//         static constexpr bool is_steady = true;
//         _NODISCARD static time_point now() noexcept { // get current time
//             const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
//             const long long _Ctr  = _Query_perf_counter();
//             static_assert(period::num == 1, "This assumes period::num == 1.");
//             // Instead of just having "(_Ctr * period::den) / _Freq",
//             // the algorithm below prevents overflow when _Ctr is sufficiently large.
//             // It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
//             // It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
//             // but the initial value of _Ctr could be large.
//             const long long _Whole = (_Ctr / _Freq) * period::den;
//             const long long _Part  = (_Ctr % _Freq) * period::den / _Freq;
//             return time_point(duration(_Whole + _Part));
//         }
//     };
//     using high_resolution_clock = steady_clock;
// } // namespace chrono
//计时器 steady_clock 类相当于秒表,操作系统只要启动就会进行时间的累加,常用于耗时的统计(精确到纳秒) 。
void Func3(){
    //静态成员函数std::chrono::steady_clock::now()获取时间的开始点
    std::chrono::time_point<std::chrono::steady_clock> start=std::chrono::steady_clock::now();
    //auto start=std::chrono::steady_clock::now();
    //执行一些代码,消耗时间
    std::vector<std::string> vec1{"banana","apple","pear"};
    std::for_each(vec1.begin(),vec1.end(),[&vec1](std::string str){
        std::cout<<str<<" ";
    });
    std::cout<<std::endl;
    //静态成员函数std::chrono::steady_clock::now()获取时间的结束点
    auto end=std::chrono::steady_clock::now();
    //计算消耗的时间,单位是纳秒
    auto dt=end-start;
    std::cout<<"耗时: "<<dt.count()<<"纳秒 ("<<(double)dt.count()/(1000*1000*1000)<<"秒) "<<std::endl;
}
int main(int argc,char* argv[]){
    Func1();
    Func2();
    Func3();
    return 0;
}

输出结果:

PS D:\时间操作 chrono 库\bin\Debug> .\main.exe
c1==c2
c1==c3
c2==c3
c1= 1
c2= 60
c3= 3600
c4= 3600000
1
1000
1000000
1000000000
2023-01-04 22:32:43
2023-01-04
22:32:43
2023-01-04 22:32:43
banana apple pear
耗时: 733400纳秒 (0.0007334秒)
PS D:\时间操作 chrono 库\bin\Debug> 

到此这篇关于C++11计时器:chrono库介绍的文章就介绍到这了,更多相关C++ chrono计时器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言学生成绩管理系统小设计

    C语言学生成绩管理系统小设计

    这篇文章主要为大家详细介绍了C语言学生成绩管理系统小设计,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • OpenCV霍夫变换(Hough Transform)直线检测详解

    OpenCV霍夫变换(Hough Transform)直线检测详解

    这篇文章主要为大家详细介绍了OpenCV霍夫变换直线检测的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • C++17新特性个人总结

    C++17新特性个人总结

    这篇文章主要介绍了C++17新特性个人总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • C语言实现扫雷小游戏详细代码

    C语言实现扫雷小游戏详细代码

    这篇文章主要为大家详细介绍了C语言实现扫雷小游戏的代码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • C语言调用摄像头生成avi视频程序

    C语言调用摄像头生成avi视频程序

    这篇文章主要为大家详细介绍了C语言如何调用摄像头生成avi视频程序,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2023-11-11
  • c与c++之间的相互调用及函数区别示例详解

    c与c++之间的相互调用及函数区别示例详解

    这篇文章主要为大家介绍了c与c++相互调用的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 关于c语言中输出字符指针的相关问题

    关于c语言中输出字符指针的相关问题

    这篇文章主要介绍了关于c语言中输出字符指针的相关问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 利用C语言结构体实现通讯录

    利用C语言结构体实现通讯录

    这篇文章主要为大家详细介绍了利用C语言结构体实现通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Opencv透视变换综合实例详解

    Opencv透视变换综合实例详解

    这篇文章主要为大家详细介绍了Opencv透视变换综合实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-05-05
  • C语言的isatty函数和ttyname函数以及sendmsg函数用法

    C语言的isatty函数和ttyname函数以及sendmsg函数用法

    这篇文章主要介绍了C语言的isatty函数和ttyname函数以及sendmsg函数用法,是C语言入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09

最新评论