《深入應用C++11》筆記-時間相關工具chrono,duration、time_point、clock

chrono是一個模版庫,包含了一系列時間相關功能。

 

duration

 

std::chrono::duration 和字面意思一樣,表示一段時間,原型是一個模板類:

 

 

 

template<
    class Rep,
    class Period = std::ratio<1>
> class duration;1234

 

Rep表示一種數值類型,用來表示Period的數量,比如int、float。
Period是ratio類型,代表用秒錶示的時間單位,默認爲std::ratio<1> ,std::ratio代表一個分數,如下代碼,N是分子,D是分母。

 

 

 

template <intmax_t N, intmax_t D = 1> struct ratio;1

 

Period是std::ratio<1>時,說明分數爲1/1,也就是1秒。

 

在chrono中預定義了一系列的duration:

 

 

 

typedef duration<long long, nano> nanoseconds;
typedef duration<long long, micro> microseconds;
typedef duration<long long, milli> milliseconds;
typedef duration<long long> seconds;
typedef duration<int, ratio<60> > minutes;
typedef duration<int, ratio<3600> > hours;123456

 

以seconds爲例,Period爲std::ratio<1>代表1s,std::chrono::seconds(10)就代表10秒。
以minutes爲例,Period爲std::ratio<60>代表60s,std::chrono::minutes(10)就代表10分鐘。
以milliseconds爲例,Period爲milli(typedef ratio<1, 1000>)代表1/1000s,std::chrono::minutes(10)就代表10毫秒。

 

duration對象常用於std::this_thread::sleep_for、std::timed_mutex::try_lock_for等函數,作爲入參:

 

 

 

std::this_thread::sleep_for(std::chrono::seconds(10));  // 等待10s1

 

另外,C++11還提供了duration之間的類型轉換duration_cast,用於不同時間精度間的裝換:

 

 

 

#include <iostream>
#include <chrono>

 

int main()
{
    std::chrono::seconds scd(10);
    std::cout << scd.count() << std::endl;   // 10
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(scd).count() << std::endl;     // 10000

 

    return 0;
}

 

// 精度高轉換成精度低的時候會導致精度丟失,需要注意
#include <iostream>
#include <chrono>

 

int main()
{
    std::chrono::milliseconds scd(10001);
    std::cout << scd.count() << std::endl;      // 10001
    std::cout << std::chrono::duration_cast<std::chrono::seconds>(scd).count() << std::endl;                     // 10

 

    return 0;
}
12345678910111213141516171819202122232425

 

time_point

 

std::chrono::time_point用於表示一個時間點,需要爲時間點指定參考時鐘(clock,clock類需要滿足指定要求,詳見https://zh.cppreference.com/w/cpp/named_req/Clock)和相對於參考時鐘步進值。它被實現成如同存儲一個 Duration 類型的自 Clock 的紀元起始開始的時間間隔的值。

 

 

 

template
<class Clock, class Duration = typename Clock::duration>
class time_point;123

 

例如以下代碼,其中system_clock::time_point被定義爲time_point,system_clock是C++11實現的clock類(一般是從格林威治標準時間開始),此處作爲time_point模板的第一個類型,第二個類型Clock::duration被定義爲microseconds,也就是說time_point表示從格林威治標準時間(1970-01-01 00:00:00.000)開始到指定時間的毫秒數。

 

 

 

#include <iostream>
#include <chrono>
using namespace std::chrono;

 

int main()
{
    system_clock::time_point now = system_clock::now();  // now表示當前時間到格林威治標準時間的毫秒數
    //等效於time_point<system_clock> now = system_clock::now();

 

    std::cout << now.time_since_epoch().count() << std::endl;  // 1534602834436896
    return 0;
}123456789101112

 

time_point對象常用於std::this_thread::sleep_until、std::timed_mutex::try_lock_until等函數,作爲入參:

 

 

 

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;

 

int main()
{
    system_clock::time_point until = system_clock::now();
    until += seconds(5);
    std::this_thread::sleep_until(until);   // 一直等待到當前時間加上5s之後的時間點

 

    return 0;
}12345678910111213

 

同樣,time_point也支持精度裝換time_point_cast:

 

 

 

#include <iostream>
#include <chrono>
using namespace std::chrono;

 

int main()
{
    time_point<system_clock> now = system_clock::now();
    std::cout << now.time_since_epoch().count() << std::endl;  // 毫秒級

 

    time_point<system_clock, hours> hour_now =
        time_point_cast<hours>(system_clock::now());
    std::cout << hour_now.time_since_epoch().count() << std::endl;   // 小時級

 

    return 0;
}123456789101112131415

 

clock

 

C++11新增了時鐘的概念,時鐘 (Clock) 概念描述由 std::chrono::duration 、 std::chrono::time_point 和獲取當前 time_point 的函數 now() 組成的一束內容,將時鐘的 time_point 原點定爲時鐘的紀元。C++11中有三種時鐘:system_clock,steady_clock和high_resolution_clock。

 

system_clock表示本地系統的時鐘,因此是不穩定的,因爲有可能被修改,上文已經舉例了一些它的用法,下面再列舉一個常用的顯示當前系統時間的用法:

 

 

 

#include <iostream>
#include <chrono>
#include <ctime>
#include <iomanip>
using namespace std::chrono;

 

int main()
{
    time_point<system_clock> now = system_clock::now();
    time_t t_now = system_clock::to_time_t(now);
    tm* tm_now = std::localtime(&t_now);
    std::cout << std::put_time(tm_now, "%Y-%m-%d %H:%M:%S") << std::endl;

 

    return 0;
}123456789101112131415

 

steady_clock表示穩定的時間間隔,後一次調用now()得到的時間總是比前一次的值大(如果中途修改了系統時間,也不影響now()的結果),所以通常用來計算時間間隔:

 

 

 

#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono;

 

int main()
{
    time_point<steady_clock> begin_time = steady_clock::now();
    std::this_thread::sleep_for(milliseconds(10));
    time_point<steady_clock> end_time = steady_clock::now();

 

    // steady_clock的精度爲納秒,裝換成毫秒輸出
    std::cout << duration_cast<milliseconds>(end_time - begin_time).count() << std::endl;

 

    getchar();
    return 0;
}1234567891011121314151617

 

high_resolution_clock 表示實現提供的擁有最小計次週期的時鐘,它可以是system_clock或steady_clock的別名,或第三個獨立時鐘。在我的實驗的機器中被定義爲:

typedef steady_clock high_resolution_clock;
---------------------
作者:WizardtoH
原文:https://blog.csdn.net/WizardtoH/article/details/81738682
 

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