目的:
希望处理“timer和clock在不同的系统中可能不同”的事实;强化时间精度提供精度中立的概念,将duration(时间段)和timepoint(时间点)从特定的clock区分开来;chrono程序组成:
duration(时间段): 某时间单位上的一个明确的tick(片可数)timepoint(时间点):一个duration和一个epoch(起始点)的组合;timepoint以某个clock为参数;Clock是一个对象,定义了timepoint的起点;duration是一个数值(表现tick个数)和一个分数(表现时间单位,以秒计时)的组合;其中分数由ratio描述; 例如:
//默认为秒为单位 std::chrono::duration<int> twentySeconds(20); //一分钟为单位(60/1) std::chrono::duration<double,std::ratio<60>> halfAMinute(0.5); //0.5 * 60 //以一毫秒为单位(1/1000) std::chrono::duration<long,std::ratio<1,1000>> oneMillisecond(1);// 1毫秒c++标准库提供的定义:
类型定义std::chrono::nanosecondsduration</*至少 64 位的有符号整数类型*/, std::nano>std::chrono::microsecondsduration</*至少 55 位的有符号整数类型*/, std::micro>std::chrono::millisecondsduration</*至少 45 位的有符号整数类型*/, std::milli>std::chrono::secondsduration</*至少 35 位的有符号整数类型*/>std::chrono::minutesduration</*至少 29 位的有符号整数类型*/, std::ratio<60>>std::chrono::hoursduration</*至少 23 位的有符号整数类型*/, std::ratio<3600>>有了这些定义:
std:: chrono:: seconds twentyseconds(20); //20秒说明:
可以计算两个duration的和,差积商;可以加减两个tick,或者加减其他duration;可以比较两个duration的大小;主要的地方:
运算的两个duration的单位类型可以不同;标准库的common_type<>为duration提供了一个重载版本,因此运算的得到的duration其单位是两个操作的单位的最大公约数;例如:
chrono::seconds d1(42); //42 秒 chrono::milliseconds d2(10); //10毫秒 //d1- d2的结果为: //拥有“41990个毫秒单位”的一个duration 可以将duration转换为不同的单位,只要彼此之间存在隐式转换;因此,可以将小时转换为秒,反向不行;说明:
duration可以进行隐式转换到一个“比较精准的单位类型”:无精度损失隐式转换但是不能转换至“比较粗糙的单位类型”:有精度损失例如: 1. 将一个42010毫秒转换到秒:42秒,这个duration中的10毫秒丢失了,这是不行的; 2. 但是可以使用duration_cast<>进行强制转换
std::chrono::seconds sec(55); std::chrono::minutes m1 = sec; //error std::chrono::minnutes m2 = std::chrono::duration_cast<std::chrono:::minutes>(sec); //ok因此,利用强制转换,可以进行将duration切割成不同的单元; 例如:
//---------省略------------- using namespace std; using namespace std::chrono; //--------------省略---------- milliseconds ms(7255042); hours hh = duration_cast<hours>(ms); minutes mm = duration_cast<minutes>(ms%hours(1)); seconds ss = duration_cast<seconds>(ms%minutes(1)); milliseconds msec = duration_cast<milliseconds>(ms%seconds(1)); cout << " " << setfill('0') << setw(2) << hh.count() << "::" << setw(2) << mm.count() << "::" << setw(2) << ss.count() << "::" << setw(2) << msec.count() << endl; //结果为: 02::00::55::42说明: 部分vs2013支持部分c++11,不能通过编译,因此需要更新的编译器;
timepoint 和clock:
clock: 定义了一个epoch(起始点)和一个tick周期;Timepoint:表现某个特定的时间点,关联到某个clock的某个正值或者负值的duration;c++标准库提供了三个clock接口:
system_clock: 所表现的timepoint关联到系统的即时时钟,这个接口提供to_time_t()和from_time_t()两个函数,允许将timepoint和“c类型的系统时间类型”time_t之间转换,意味着可以转换到日历时间;
steady_clock: 保证绝对不会被调整;当实际时间流逝的时候,timepoint值不会减少,用来计算时间间隔;
high_resolution_clock: 表现的是当前系统中带有最短tick的clock;它可能是system_clock或stable_clock的同义词。
定义为:
template <class Clock, class Duration = typename Clock::duration> class time_point;四个特定的timepoint: - Epoch: 由任何clock的time_point的默认构造函数产出; - Current time: 由任何的clock的static成员函数now()产出; - Minimum timepoint: 由任何clock的time_point的static成员函数min()产生; - Maximum timepoint: 由任何clock的time_point的static成员函数max()产出; 例子:
#include <chrono> #include <iostream> #include <iomanip> using namespace std; using namespace std::chrono; string asString (const chrono::system_clock::time_point & tp) { time_t t = chrono::system_clock::to_time_t(tp); string ts = ctime(&t); return ts; } int main(){ chrono::system_clock::time_point tp; cout<<"epoch: "<<asString(tp) ; tp = chrono::system_clock::now(); cout<<"now: "<<asString(tp); //tp = chrono::system_clock::time_point::min(); //cout<<"min: "<<asString(tp); //tp = chrono::system_clock::time_point::max(); //cout<<"max: "<<asString(tp); }min()和max()出错,不知道哪里有问题! 输出为:
epoch: Thu Jan 01 08:00:00 1970 now: Thu Aug 31 11:20:44 2017说明:
只有system_clock才有接口从time_point转到time_t类型;说明:
time_t通常只是“始于unix epoch(1970年1月1日)的秒数;”结构体 tm的成员:
int tm_sec //秒 在minute后 – [0, 60][note 1] int tm_min //分钟,在1小时后 - [0,59] int tm_hour //小时,自午夜开始 - [0,23] int tm_mday //月的一天 - [1,31] int tm_mon //1月,0开始 - [0,11] int tm_year //年,自1900年以来 int tm_wday //自上周日以来- [0,6] int tm_yday //天,自1月1日 - [0,365] int tm_isdst //夏令时间标志。大于0表示夏令时,如果夏令时没有效果,则为零,如果信息不可用,小于零。 (公开成员对象)duration和timepoint可以用来停滞线程或者程序; 例如:
sleep_for()和sleep_until():由this_thread提供的来停滞线程;try_lock_for()和try_lock_until(),用来等待一个mutex时指定最大时间段;wait_for()和wait_until(),用来等待某条件成立或等待一个future时指定最大时间段;说明:
所有以..for()结束的停滞函数需要一个duration所有以..until()结束的停滞函数需要一个timepoint这些timer都不保证绝对精准例子:
this_thread::sleep_for(chrono::seconds(10)); //停滞当前线程10秒 this_thread::sleep_until(chrono:system_clock::now() + chrono::seconds(10) ) ; //停滞当前线程直到system_clock来到比当前多10秒的timepoint