c11 chrono详解
转自:https://blog.csdn.net/hou8389846/article/details/77962343#commentBox
chrono是c++11的时间库,提供计时,时钟等功能。
了解chrono,主要了解时间段(duration)和时间点(time_point)的概念。
1、精度(ratio)
时钟节拍(时间精度):
template<intmax_t N, intmax_t D = 1> class ratio;
其中N表示分子(对应period::num),D表示分母(默认用秒表示的时间单位,对应period::den)。
常用的单位:
ratio<3600, 1> hours;
ratio<60, 1> minutes;
ratio<1, 1> seconds;
ration<1, 1000> milliseconds;
test:
#include <iostream>
#include <chrono>
using namespace std;
int main(int argc, char *argv[])
{
cout << "milliseconds = ";
cout << std::chrono::milliseconds::period::num << "/" \
<< std::chrono::milliseconds::period::den << "s" << endl; //out: 1/1000s
typedef std::chrono::duration<int, std::ratio<1, 2> > halfseconds;
cout << "halfseconds = ";
cout << halfseconds::period::num << "/" \
<< halfseconds::period::den << "s" << endl; //out: 1/2s
cout << "microseconds = ";
cout << std::chrono::microseconds::period::num << "/" \
<< std::chrono::microseconds::period::den << "s" << endl; //out: 1/1000000s
return 0;
}
2、时间段(duration)
template<class Rep, class Period = ratio<1> > class duration;
std::chrono::duration(时间段)表示一段时间,如半个小时,12.88秒,半天,一炷香的时间等等。
Rep表示一种数值类型,用来表示Period数量。如:int,float, double;
Period是ratio类型,用来表示时间精度。如:hours,seconds,minutes等;
chrono中宏定义了很多特例化的duration:
typedef std::chrono::duration<int64_t> seconds;
typedef std::chrono::duration<int64_t, ratio<60> > munites;
typedef std::chrono::duration<int64_t, ratio<3600> > hours;
typedef std::chrono::duration<int64_t, ratio<1, 1000> > milliseconds;
构造函数
duration() = default;
duration(const duration& dtn);
template<class Rep, class Period>
constexpr duration(const duration<Rep, Period> &dtn);
template<class Rep>
constexpr duration(const Rep & rep);
成员函数count()显示单位时间的数量
example:
#include <chrono>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
cout << "microseconds = ";
cout << std::chrono::microseconds::period::num << "/" \
<< std::chrono::microseconds::period::den << "s" << endl;
typedef std::chrono::duration<int64_t, ratio<1, 2> > halfseconds;
halfseconds halfsec(1000);
cout << halfsec.count() << endl; //out: 1000
cout << "halfsec(1000) = " << halfsec.count()*halfseconds::period::num/ \
halfseconds::period::den << "s" << endl; //out: 500s
std::chrono::milliseconds ms(2000);
cout << ms.count() << endl; //out: 2000
cout << "milliseconds(2000) = " << halfsec.count()* \
std::chrono::milliseconds::period::num/ \
std::chrono::milliseconds::period::den << "s" << endl; //out: 1s
return 0;
}
时间段的显示转换由std::chrono::duration_cast<> 来实现。
std::chrono::milliseconds ms(54800);
std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(ms);//out:sec = 54S
3、时间点(time_point)
template<class Clock, class Duration = typename Clock::duration>
class time_point;
std::chrono::time_point表示一个具体时间(能用计算机时间表示),如:今天下午3点,火车出发时间等等。
模板第一个参数Clock指定所有的时钟(标准库中有三种时钟:system_clock、steady_clock和high_resulotion_clock),第二个参数表示时间的计量单位(特化std::chrono::duration<>)。
时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。
构造函数
time_point() = default;//默认构造函数
template<class Duration2>
time_point(const time_point<clock, Duration2> &tp); //拷贝构造函数
explicit time_point(const duration &dtn);//用duration来构造,就是距离时间戳的长度
duration time_since_epoch()
此函数表示当前时间距离时间戳的时间长度,即当前时间点到时间戳(1970年1月1日 00:00)的时间距离,返回duration的精度与构造time_point的Clock有关。
test
#include <chrono>
#include <iostream>
#include <ctime>
using namespace std;
int main(int argc, char *argv[])
{
using namespace std::chrono;
time_point<system_clock, seconds> tp(seconds(2));
cout << "time_since_epoch = " << tp.time_since_epoch().count() << endl;
//转换成ctime,打印时间点
time_t tt = system_clock::to_time_t(tp);
char a[50] = {0};
ctime_s(a, 50, &tt);
cout << a << endl;//out:Thu Jan 01 08:00:02 1970
return 0;
}
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()的返回值都依赖于时钟的精度。检测精度的方法:
#include <chrono>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
using namespace std::chrono;
cout << "system clock: " \
<< system_clock::period::num << "/" << \
system_clock::period::den << "s" << endl; //out:1/1000000000(1ns)
cout << "steady clock: " \
<< steady_clock::period::num << "/" << \
steady_clock::period::den << "s" << endl; //out:1/1000000000(1ns)
cout << "high resolution clock: " \
<< high_resolution_clock::period::num << "/" << \
high_resolution_clock::period::den << "s" << endl; //out:1/1000000000(1ns)
return 0;
}
成员函数
//获取当前系统时间
static time_point now() noexcept;
//time_point的转换函数
template<class ToDuration, class Clock, class Duration>
time_point<Clock, ToDuration> time_point_cast(const time_point<Clock,Duration> &tp);
//time_point转换成ctime(秒)
to_time_t()
//ctime转换成time_point
from_time_t()
综合应用
输出当前时间,并且计算当前的时间距离1970年1月1日00:00的毫秒数,计算两个时间的时间长度。
#include <chrono>
#include <iostream>
#include <ctime>
using namespace std;
int main(int argc, char *argv[])
{
using namespace std::chrono;
//显示当前系统时间及距离时间戳的时间长度(秒)
typedef chrono::time_point<chrono::system_clock, chrono::seconds> secClock;
secClock sec = chrono::time_point_cast<chrono::seconds>(chrono::system_clock::now());
time_t tt = system_clock::to_time_t(sec);
char a[50];
ctime_s(a, sizeof (a), &tt);
cout << "time now[s] : " << a;
cout << "to 1970-1-1,00:00[s] " << sec.time_since_epoch().count() << "s" << endl;
for(unsigned int i = 0; i < 1000000000; ++i) {
if(i%10000000 == 0) {
cout << "*";
}
}
cout << endl;
//显示当前系统时间及距离时间戳的时间长度(毫秒)
typedef chrono::time_point<chrono::system_clock, chrono::milliseconds> milliClock;
milliClock ms = chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now());
time_t mt = chrono::system_clock::to_time_t(ms);
char cmt[50] = {0};
ctime_s(cmt, sizeof (cmt), &mt);
cout << "now time[ms] = " << cmt;
cout << "to 1970-1-1,00:00[ms] " << ms.time_since_epoch().count() << "ms" << endl;
//计算两个时间的时间长度[秒级]
cout << "from sec to ms :" << (chrono::time_point_cast<chrono::seconds>(ms) - sec).count() << endl;
return 0;
}
上一篇: vue3.0修改浏览器title
下一篇: c11 decltype与auto