std::chrono庫的使用

std::chrono學習筆記

chrono是一個模版庫,提供關於日期和時間的一些功能。
先舉個例子,如果我想知道看這篇博文花了多長時間:
(1)首先需要有一個能提供時鐘(clock)的設備(電腦、手機、手錶、掛鐘等)
(2)記錄開始閱讀和結束閱讀的時間點(time_point);
(3)計算兩次的時間之差就是閱讀持續時間(duration)。
chrono的模板庫常用的3個模板也是這3個:duration、time_point、clock
在使用時,需要引用chrono頭文件。

#include <chrono>

clock

既然談到時間,總需要找一個時鐘作爲參照吧,就像我們想知道當前時間,可以看牆上的掛鐘,可以看手錶,可以看手機。clock就是這個時鐘,在計算機中一般都會有一套或多套時鐘系統供程序使用。
在std::chrono庫中,有3種時鐘:

  • system_clock
  • steady_clock
  • hight_definition_clock
    一般情況下,他們3個沒有太大的區別,hight_definition_clock、steady_clock僅僅是system_clock的typedef,但是有爲什麼要區分呢,因爲在有些情況下,他們是存在差異的。

情況1:system_clock和steady_clock的差異
比如windows系統可以提供時鐘,如果認爲時間不準,我們還可以進行調整。在沒有調整時間前,system_clock和steady_clck是一樣的,他們的讀數都是單調勻速增加的;但是如果調整時間後,它們兩者的讀數就會出現差異,system_clock的讀數就會出現跳變,而steady_clock依然保持線性單調遞增,不受clock調整的影響,這個特點非常方便我們統計時間耗時(duration)。
情況2:system_clock與hight_definition_clock的差異
如果系統提供的時鐘(clock)不止一種,有的時鐘精度高(分辨率),有的精度低,hight_definition_clock使用時精度最高的clock,但是system_clock就不一定了。

clock主要用於獲取當前的時間,通過now()獲取,方法如下。關於time_point在下面講解。

std::chrono::system_clock::time_point current_time = std::chrono::system_clock::now();

time_point

time_point是具體的時間,比如某年某月某日幾點幾分幾秒,time_point依賴於clock的計時。
通過上文中的方法可以將當前時間賦值給current_time,current_time的時間數據是一個數字,表示當前時間是經過了多少個計時單位了,那麼計時的起點是什麼時候呢?爲了讓不同地區、不同國家、不同的設備有一個統一標準,可以通過time_since_epoch().count()計算以 1970 年 1 月 1 日 00:00 UTC 爲起點的時間。

std::chrono::system_clock::time_point current_time = std::chrono::system_clock::now();
cout << "current_time = " << current_time.time_since_epoch().count() << endl;

duration

duration表示一段時間,也就是持續時間,是一個時間的長度,比如1個小時、35秒、33毫秒。
它的模板類如下,包含兩個參數,Rep是必需要指定的,Period是可選擇輸入的,簡單的說Rep表示數據的類型,如int、float等;Period可以理解爲時間的單位,默認是1秒,自己也可自定義修改,就是duration每增加1與之對應的時間是多少。

template <class Rep, class Period = ratio<1> > class duration;
  • 使用默認1秒作爲計量單位
typedef std::chrono::duration<int> t_int;
typedef std::chrono::duration<double> t_float;
// duration每增加1,表示的時間的變化量爲1秒
  • 使用自定義的值作爲計量單位
// duration每增加1,時間的變化爲0.001秒
typedef std::chrono::duration<float, std::ratio<1,1000>> mSec_float; // 1/1000秒作爲計量單位,也就毫秒
// duration每增加1,時間的變化爲60秒
typedef std::chrono::duration<int, ratio<60, 1>> minute_int; // 60/1秒爲計量電位,也就是1分鐘

上面ratio有兩個參數ratio<num, den>,那麼實際的單位爲num/den秒。

除了可以通過ratio來自定義時間的計量單位,也可以使用std庫中預定義好的變量,本質上也是使用ratio定義好的。
在這裏插入圖片描述
使用方法如下

std::chrono::duration<int, std::milli>  // 毫秒
std::chrono::duration<int, std::micro>  // 微秒
std::chrono::duration<int, std::nano>   // 納秒
  • 如何定義、修改duration的變量
#include <chrono>
#include <iostream>
using namespace std;
int main(int argc, int** argv[]) {
    typedef std::chrono::duration<int, std::milli> mSec_t;
    mSec_t t1(2000);
    cout << "t1 = " << t1.count() << endl;
    // t1 = 3000; // 不能這樣賦值
    t1 = mSec_t(3000); // 修改變量
    cout << "t1 = " << t1.count() << endl;

    system("pause");
    return 0;
}

一個例子

通過獲取兩個時刻的時間,然後計算時間長度。

#include <chrono>
#include <iostream>
#include <thread>
#include <ctime>

using namespace std;

int main() {
   // DEMO:通過獲取兩個時刻的時間,然後計算時間長度

    using namespace std::chrono;

    // Step one: 定義一個clock
    typedef system_clock sys_clk_t;

    // Step two: 分別獲取兩個時刻的時間
    typedef system_clock::time_point time_point_t;
    // 第1個時間
    time_point_t time01 = sys_clk_t::now();
    // 延時5秒
    std::this_thread::sleep_for(std::chrono::duration<int>(5));
    // 第2個時間
    time_point_t time02 = sys_clk_t::now();

    // Step three: 計算時間差
    cout << "dt_time(system_clock period) = " << (time02 - time01).count() << endl;

    typedef duration<int, std::ratio<1, 1000>> mili_sec_t;
    cout << "\ndt_time(user define period) = " << 
    (time_point_cast<mili_sec_t>(time02) - time_point_cast<mili_sec_t>(time01)).count() << endl;
    
    system("pause");
    return 0;
}

運行結果如下:
在這裏插入圖片描述
system_clock的計時單位是10-7秒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章