1. 程式人生 > >C++11標準庫chrono庫使用

C++11標準庫chrono庫使用

chrono是C++11新加入的方便時間日期操作的標準庫,它既是相應的標頭檔案名稱,也是std名稱空間下的一個子名稱空間,所有時間日期相關定義均在std::chrono名稱空間下。通過這個新的標準庫,可以非常方便進行時間日期相關操作。
chrono庫主要包含了三種類型:duration, time_point 和 clock。

Duration(時間間隔)

chrono庫中用一個duration模板類,用來表示一段時間間隔,可以表示幾秒鐘、幾分鐘或者幾個小時的時間間隔。

原型

template<typename _Rep, typename _Period = ratio<1
>> struct duration { typedef _Rep rep; ... private: rep __r; //內部維護的計數個數成員 ... };

第一個模版引數是數值型別,表示時鐘個數;第二個為std::ratio,用來表示每個時鐘的週期(單位為秒)
ratio的原型是

template<intmax_t _Num, intmax_t _Den = 1>
struct ratio;

這是一個非型別模版引數的模版類,intmax_t是定義在cstdint標頭檔案中的內建型別。第一個引數代表分子,第二個代表分母,兩者表示一個通用的比率型別。它們必須在編譯期間確定為常量值

。分母預設為1,因此ratio<60>代表60,ratio<1, 1000>代表0.001。為了方便使用,在ratio標頭檔案中定義了常用比率的別名:

  typedef ratio<1,       1000000000000000000> atto;
  typedef ratio<1,          1000000000000000> femto;
  typedef ratio<1,             1000000000000> pico;
  typedef ratio<1,                1000000000> nano;
  typedef ratio<1,                   1000000
>
micro; typedef ratio<1, 1000> milli; typedef ratio<1, 100> centi; typedef ratio<1, 10> deci; typedef ratio< 10, 1> deca; typedef ratio< 100, 1> hecto; typedef ratio< 1000, 1> kilo; typedef ratio< 1000000, 1> mega; typedef ratio< 1000000000, 1> giga; typedef ratio< 1000000000000, 1> tera; typedef ratio< 1000000000000000, 1> peta; typedef ratio< 1000000000000000000, 1> exa;

回到duration模板類,預設的比率為ratio<1>,也就是一個時鐘數_Rep代表1秒。為了方便使用,chrono庫定義瞭如下的常用時間單位:

/// nanoseconds
typedef duration<int64_t, nano>     nanoseconds;

/// microseconds
typedef duration<int64_t, micro>    microseconds;

/// milliseconds
typedef duration<int64_t, milli>    milliseconds;

/// seconds
typedef duration<int64_t>       seconds;

/// minutes
typedef duration<int, ratio< 60>>   minutes;

/// hours
typedef duration<int, ratio<3600>>  hours;

通過定義上述常用型別,可以非常方便的使用:

//執行緒休眠10秒
std::this_thread::sleep_for(std::chrono::seconds(10));

成員

duration內部維護了週期個數rep和週期period,兩者結合用來表示間隔時間。

count

用來獲取內部維護的rep型別的週期個數,或稱為tick數。即定義變數的實參

chrono::milliseconds ms(10);//10個tick
chrono::duration<double, std::ratio<1, 30>> dur(10.5);//10.5 tick
cout << "ms: " << ms.count() << '\t' << "dur: "<< dur.count() << endl;

上述程式碼輸出:

ms: 10 dur : 10.5

靜態成員函式

duration例項化後,對於給定的rep表示週期個數的型別,提供了min、max和zero三個靜態成員函式,用來獲取當前型別能表示的最小、最大週期數和0週期數代表的duration物件。

cout << chrono::seconds::max().count() << endl;

//輸出結果為:9223372036854775807

運算操作

duration支援基本所有算術運算操作,而且不同單位之間的可以自動進行匹配。這是通過duration_cast模板類實現的。

chrono::minutes t1(5);
chrono::seconds t2(30);
chrono::seconds t3 = t1 - t2;
cout << t3.count() << '\t' << chrono::duration_cast<chrono::minutes>(t3).count() << endl;

//對於型別轉換會進行舍入
//輸出結果:270 4

Time point

chrono庫中用一個time_point模板類,表示一個時間點,如生日、今天日落時刻等,通過一個相對epoch的時間間隔duration來實現,epoch就是1970-1-1時刻,對於同一個時鐘來說,所有的time_point的epoch都是固定的。這個類可以與標準庫ctime結合起來顯示時間,ctime內部的time_t型別就是代表這個秒數。

原型

template<typename _Clock, typename _Dur = typename _Clock::duration>
struct time_point
{
typedef _Clock                      clock;
typedef _Dur                        duration;
typedef typename duration::rep              rep;
typedef typename duration::period           period;
private:
    duration __d; //維護的內部duration成員
...

};

第一個引數為當前計時使用的時鐘,可選為“system_colck”、“steady_colck”、“high_resolution_clock”或者是自定義的時鐘類;
第二個引數為時間間隔,預設為使用的時鐘相同的間隔。
內部維護了一個duration私有成員,通過制定的時鐘,來確定距離epoch時間點的間隔。

成員

chrono::time_point<system_clock> tp = chrono::system_clock::now();
cout << tp.time_since_epoch().count() << endl;

//輸出為:1452672734311762303
//system_clock的ratio為nano

運算

與duration類似,time_point也提供了靜態成員min和max,以及算術運算操作,這些都是通過內部維護的duration成員進行的,duration成員的各種操作由前面所述的提供保障,time_point就只需要通過time_since_epoch獲取私有duration成員進行呼叫即可。還提供了與duration直接進行”+=”和“-=”的運算操作,對於普通的算術運算,如果有一個運算元型別為duration,則是在time_point型別運算元內部維護的duration成員上進行操作,則返回型別為time_point;當兩者均為time_point型別時,返回型別為二者維護的duration成員之差,從而返回型別也為duration。

表示當前系統時鐘,共有三種:

  • system_clock:從系統獲取時鐘
  • steady_clock:不能被修改的時鐘
  • high_resolution_clock:高精度時鐘,實際上是system_clock或者steady_clock的別名,最小精度是納秒

system_clock

system_clock 提供三個靜態的函式,可以用於time_point提供了與C API的時間互動的良好定義。因此,可以很容易與time_t型別打交道。介面函式如下:

//get current time
static time_point now() noexcept;

//time_point conver to time_t
static time_t to_time_t (const time_point& tp) noexcept;

//convert time_t to time_oint
std::chrono::system_clock::from_time_t
static time_point from_time_t (time_t t) noexcept;

system_clock 和ctime函式使用demo:


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

int main ()
{
    using std::chrono::system_clock;

    std::chrono::duration<int,std::ratio<60*60*24> > one_day (1);

    //current time
    system_clock::time_point today = system_clock::now();

    //tomorrow time
    system_clock::time_point tomorrow = today + one_day;

    //convert time type   
    time_t tmTomorrow = system_clock::to_time_t ( tomorrow );

    //time string
    std::cout << "tomorrow will be: " << ctime(&tmTomorrow);

    struct tm *p;   
    p = localtime(&tmTomorrow); /*轉換為struct tm結構的當地時間*/  
    printf("%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday); 

    return 0;
}

執行結果:

tomorrow will be: Sun Feb 11 09:13:07 2018
2018/2/11 

steady_clock

steady_clock 專門用於計算時間差的工具,steady_clock 類只有一個靜態函式now(),用於獲取當前的時間,計算時間差的方式如下:

#include <iostream>
#include <chrono>

int main()
{
    typedef std::chrono::steady_clock  STEADY_CLOCK;

    STEADY_CLOCK::time_point t1 = STEADY_CLOCK::now();

    std::cout << "print 1000 stars" << std::endl;

    for (int i=1; i<=1000; ++i)
    {
        std::cout << "*";
        if (0 == i % 50) 
        {
            std::cout << "\n";
        }
    }

    std::cout << std::endl;

    STEADY_CLOCK::time_point t2 = STEADY_CLOCK::now();

    //毫秒
    std::chrono::duration<double, std::milli> dTimeSpan = std::chrono::duration<double,std::milli>(t2-t1);

    std::cout << "print start time span : " << dTimeSpan.count() << "ms\n";   
}

執行結果:

print 1000 stars
****************************....
print start time span : 0.091333ms

相關推薦

C++11標準chrono使用

chrono是C++11新加入的方便時間日期操作的標準庫,它既是相應的標頭檔案名稱,也是std名稱空間下的一個子名稱空間,所有時間日期相關定義均在std::chrono名稱空間下。通過這個新的標準庫,可以非常方便進行時間日期相關操作。 chrono庫主要包含

c++11 標準函數 std::move 和 完美轉發 std::forward

標準庫函數 這樣的 除了 值引用 sin 引入 語言 優先 ace c++11 標準庫函數 std::move 和 完美轉發 std::forward #define _CRT_SECURE_NO_WARNINGS #include <iostream>

使用c++11標準轉換字元編碼

#include <stdio.h> #include <locale> #include <codecvt> const std::string ws2s( const std::wstring& src ) { std

Visual Studio 11開發指南(19)C++11更新-並行模式和代理

                 Visual Studio 11,具備並行模式庫和代理庫、 更輕鬆地開發多核處理器上執行的並行程式碼。這些庫的主要範例是根據任務 和併發執行庫,自定義的排程程式 進行處理的。到目前為止,處理任務的的概念原型,就使用task_handle ●型別 如下所示:1.task_gro

C++11併發程式設計(一)——初始C++11多執行緒

1 前言   C++11標準在標準庫中為多執行緒提供了元件,這意味著使用C++編寫與平臺無關的多執行緒程式成為可能,而C++程式的可移植性也得到了有力的保證。   在之前我們主要使用的多執行緒庫要麼

Linux上C語言標準數學函式的引用

       eclipse安裝了CDT外掛之後就可以在上面編輯、編譯、連結、執行C/C++程式了,但是不同於gcc編譯器的純命令列操作,eclipse上基本上都是通過圖形化介面實現的,只需要進行簡單的設定就可以實現特定的功能。函式庫通常可以靜態連結庫(*.a檔案)和動態

gcc g++支持C++11 標準編譯及其區別

包含 別名 glob sin 你會 con 並且 c++程序 轉換成 g++ -g -Wall -std=c++11 main.cpp gcc -g -Wall -std=c11 main.cpp 如果不想每次寫這個-std=C++11這個選項該怎麽辦呢?   方法出

介紹C++11標準的變長參數模板

class 情況下 展開 containe printf 一個 structs .cpp 實例 轉自:https://www.cnblogs.com/zenny-chen/archive/2013/02/03/2890917.html 目前大部分主流編譯器的最新版本均

sublime text3配置c++ 11標準

For Windows { "shell_cmd": "g++ -std=c++11 \"${file}\" -o \"${file_path}/${file_base_name}.exe\"", "file_regex": "^(..[^:]*):([0-9]+

C++ 11標準簡單實現觀察者模式

觀察者模式簡單理解:被觀察者的狀態發生變化,觀察者的行為同時也發生變化。 觀察者模式的簡單應用:           1.宣告被觀察者物件。           2.觀察者向被觀察者註冊訊息相應函式。           3.觀察者屬性發生變化,同時註冊上的觀察者出發

c++11計時:chrono

#include <chrono> std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 某段程式碼 std:

如何在windows下使用c++11標準 (Dev C++切換 C++ 11 環境)

安裝之後需要簡單設定一下。 設定方法:Tools - Compiler Options - Settings - Code Generation Lauguage standaerd(-std)選項下拉選單中選擇 GNU C++11 Dev-Cpp 5.4.2

linux下安裝或升級GCC4.8.2,以支持C++11標準[轉]

生成 文件內容 手動安裝 網址 com disable string main cti 在編譯kenlm的時候需要安裝gcc, 然後還需要安裝g++。 g++安裝命令:sudo apt-get install g++ ----------------------以下為網上

linux下安裝或升級GCC4.8.2,以支援C++11標準[轉]

在編譯kenlm的時候需要安裝gcc, 然後還需要安裝g++。 g++安裝命令:sudo apt-get install g++ ----------------------以下為網上轉載內容,加上自己修改------------------ 本文主要介紹在Linux系統下,如何升級GCC以支援C+

C++11 標準新特性: 右值引用與轉移語義

https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 特性的目的 右值引用 (Rvalue Referene) 是 C++ 新標準 (C++11, 11 代表 2011 年 ) 中引入的新特性

C++11 標準新特性:Defaulted 和 Deleted 函式

https://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/index.html 本文將介紹 C++11 標準的兩個新特性:defaulted 和 deleted 函式。對於 default

C++11標準之右值引用(ravalue reference)(轉載)

臨時物件的產生和拷貝所帶來的效率折損,一直是C++所為人詬病的問題。但是C++標準允許編譯器對於臨時物件的產生具有完全的自由度,從而發展出了Copy Elision、RVO(包括NRVO)等編譯器優化技術,它們可以防止某些情況下臨時物件產生和拷貝。下面簡單地介紹一下Copy Elision、RVO

C++11標準下STL的容器分類

第一種:順序容器 1、vector:可變陣列。支援快速隨機訪問。在尾部之外的位置插入或刪除元素可能很慢; 2、deque:雙端佇列。支援快速隨機訪問。在頭尾位置插入/刪除速度很快; 3、list:雙向連結串列。只支援雙向順序訪問。在list任何位置進行插入/刪除操作速度都很

C++11標準---委託建構函式

委託建構函式 1.概念:一個委託建構函式通過所屬類的其它建構函式執行自己的初始化功能,或者是說把自己的職責委託給了其它建構函式去完成 2.格式 與成員初始化列表初始化成員變數類似,在建構函式後面用:號連線一個建構函式 下面的例項中,兩個委託建構函式把自己的職責交給了其他

C++11標準---型別處理(using、auto、decltype)

一、類型別名 類型別名:是一個名字,它是同種型別的同義詞 兩種方法可用於定義類型別名 關鍵字:typedef C++11新標準中的:using 1.typedef 用法 typedef double wages; //wages是double的同義詞 ty