C++11計時器之chrono庫簡介
C++11計時器:chrono庫介紹
C++11有了chrono庫,可以在不同系統(tǒng)中很容易的實現(xiàn)定時功能。
要使用chrono庫,需要#include,其所有實現(xiàn)均在std::chrono namespace下。注意標(biāo)準(zhǔn)庫里面的每個命名空間代表了一個獨立的概念。
chrono是一個模版庫,使用簡單,功能強(qiáng)大,只需要理解三個概念:duration、time_point、clock
一 、時鐘-CLOCK
chrono庫定義了三種不同的時鐘:
std::chrono::system_clock: 依據(jù)系統(tǒng)的當(dāng)前時間 (不穩(wěn)定) std::chrono::steady_clock: 以統(tǒng)一的速率運行(不能被調(diào)整) std::chrono::high_resolution_clock: 提供最高精度的計時周期(可能是steady_clock或者system_clock的typedef)
二、這三個時鐘有什么區(qū)別呢?
system_clock就類似Windows系統(tǒng)右下角那個時鐘,是系統(tǒng)時間。明顯那個時鐘是可以亂設(shè)置的。明明是早上10點,卻可以設(shè)置成下午3點。
steady_clock則針對system_clock可以隨意設(shè)置這個缺陷而提出來的,他表示時鐘是不能設(shè)置的。
high_resolution_clock則是一個高分辨率時鐘。
這三個時鐘類都提供了一個靜態(tài)成員函數(shù)now()用于獲取當(dāng)前時間,該函數(shù)的返回值是一個time_point類型,
system_clock除了now()函數(shù)外,還提供了to_time_t()靜態(tài)成員函數(shù)。用于將系統(tǒng)時間轉(zhuǎn)換成熟悉的std::time_t類型,得到了time_t類型的值,在使用ctime()函數(shù)將時間轉(zhuǎn)換成字符串格式,就可以很方便地打印當(dāng)前時間了。
#include<iostream> #include<vector> #include<string> #include<ctime>//將時間格式的數(shù)據(jù)轉(zhuǎn)換成字符串 #include<chrono> using namespace std::chrono; using namespace std; int main() { //獲取系統(tǒng)的當(dāng)前時間 auto t = system_clock::now(); //將獲取的時間轉(zhuǎn)換成time_t類型 auto tNow = system_clock::to_time_t(t); //ctime()函數(shù)將time_t類型的時間轉(zhuǎn)化成字符串格式,這個字符串自帶換行符 string str_time = std::ctime(&tNow); cout<<str_time; return 0; }
三、持續(xù)的時間 - duration
td::chrono::duration<int,ratio<60,1>> ,表示持續(xù)的一段時間,這段時間的單位是由ratio<60,1>決定的,int表示這段時間的值的類型,函數(shù)返回的類型還是一個時間段duration
std::chrono::duration<double,ratio<60,1>>
由于各種時間段(duration)表示不同,chrono庫提供了duration_cast類型轉(zhuǎn)換函數(shù)。
duration_cast用于將duration進(jìn)行轉(zhuǎn)換成另一個類型的duration。
duration還有一個成員函數(shù)count(),用來表示這一段時間的長度
#include<iostream> #include<string.h> #include<chrono> using namespace std::chrono; using namespace std; int main() { auto start = std::chrono::steady_clock::now(); for(int i=0;i<100;i++) cout<<"nice"<<endl; auto end = std::chrono::steady_clock::now(); auto tt = std::chrono::duration_cast<microseconds>(end - start); cout<<"程序用時="<<tt.count()<<"微秒"<<endl; return 0; }
四、時間點 - time_point
std::chrono::time_point 表示一個具體時間,如上個世紀(jì)80年代、你的生日、今天下午、火車出發(fā)時間等,只要它能用計算機(jī)時鐘表示。鑒于我們使用時間的情景不同,這個time point具體到什么程度,由選用的單位決定。一個time point必須有一個clock計時
設(shè)置一個時間點:
std::time_point<clock類型> 時間點名字
//設(shè)置一個高精度時間點 std::time_point<high_resolution_clock> high_resolution_clock::now();
//設(shè)置系統(tǒng)時鐘 std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now();
另一個實例:
#define _CRT_SECURE_NO_WARNINGS //localtime()需要這個宏 #include<iostream> #include<chrono> #include<vector> #include<string> #include<algorithm> //#include<stdio.h> #include<iomanip> //put_time需要的頭文件 #include<sstream> // template <class _Rep> // struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type // template <class _Rep> // _INLINE_VAR constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; // // STRUCT TEMPLATE duration_values // template <class _Rep> // struct duration_values { // gets arithmetic properties of a type // _NODISCARD static constexpr _Rep zero() noexcept { // // get zero value // return _Rep(0); // } // _NODISCARD static constexpr _Rep(min)() noexcept { // // get smallest value // return numeric_limits<_Rep>::lowest(); // } // _NODISCARD static constexpr _Rep(max)() noexcept { // // get largest value // return (numeric_limits<_Rep>::max)(); // } // }; //時間長度 void Func1(){ //chrono重載了各種運算符 std::chrono::hours c1(1); //1小時 std::chrono::minutes c2(60); //60分鐘 std::chrono::seconds c3(60*60); //60*60s std::chrono::milliseconds c4(60*60*1000); //60*60*1000毫秒 std::chrono::microseconds c5(60*60*1000*1000); //微秒 溢出 std::chrono::nanoseconds c6(60*1000*1000*1000);//納秒 溢出 if(c1==c2){ std::cout<<"c1==c2"<<std::endl; } if(c1==c3){ std::cout<<"c1==c3"<<std::endl; } if(c2==c3){ std::cout<<"c2==c3"<<std::endl; } //獲取時鐘周期的值,返回的是int整數(shù) std::cout<<"c1= "<<c1.count()<<std::endl; std::cout<<"c2= "<<c2.count()<<std::endl; std::cout<<"c3= "<<c3.count()<<std::endl; std::cout<<"c4= "<<c4.count()<<std::endl; std::chrono::seconds c7(1); //1秒 std::chrono::milliseconds c8(1*1000); //1000毫秒;1s std::chrono::microseconds c9(1*1000*1000); //1000*1000微秒 1s std::chrono::nanoseconds c10(1*1000*1000*1000);//1000*1000*1000納秒 1s; std::cout<<c7.count()<<std::endl; std::cout<<c8.count()<<std::endl; std::cout<<c9.count()<<std::endl; std::cout<<c10.count()<<std::endl; } //系統(tǒng)時間 /** * @brief * * system_clock 類支持了對系統(tǒng)時鐘的訪問, 提供了三個靜態(tài)成員函數(shù): 返回當(dāng)前時間的時間點。 static std::chrono::time_point<std::chrono::system_clock> now() noexcept; 將時間點 time_point 類型轉(zhuǎn)換為 std::time_t 類型。 static std::time_t to_time_t( const time_point& t ) noexcept; 將 std::time_t 類型轉(zhuǎn)換為時間點 time_point 類型。 static std::chrono::system_clock::time_point from_time_t( std::time_t t ) noexcept; */ void Func2(){ //靜態(tài)成員函數(shù) static std::chrono::time_point<std::chrono::system_clock> now() noexcept //這些都可以簡寫用auto now=std::chrono::system_clock()::now()接收 //1、靜態(tài)成員函數(shù) static std::chrono::system_clock::now()用來獲取系統(tǒng)時間,C++時間 std::chrono::time_point<std::chrono::system_clock> now=std::chrono::system_clock::now(); //2、靜態(tài)成員函數(shù) static std::chrono::system_clock::to_time_t()把C++系統(tǒng)時間轉(zhuǎn)換為time_t (utc時間) time_t t_now=std::chrono::system_clock::to_time_t(now); //3、std::localtime()函數(shù)把time_t時間轉(zhuǎn)換為本地時間(北京時間) // std::localtime()不是線程安全的,VS用localtime_t()代替,linux用local_time_r()代替 //tm結(jié)構(gòu)體 tm* tm_now=localtime(&t_now); //格式化輸出tm結(jié)構(gòu)體中的成員 std::cout<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S")<<std::endl; std::cout<<std::put_time(tm_now,"%Y-%m-%d")<<std::endl; std::cout<<std::put_time(tm_now,"%H:%M:%S")<<std::endl; //但是通常C++一般不打印出時間,而是把時間存儲到一個字符串中 std::stringstream ss; //創(chuàng)建stringstream對象 ss,需要包含<sstream>頭文件 ss<<std::put_time(tm_now,"%Y-%m-%d %H:%M:%S"); std::string time_str=ss.str(); std::cout<<time_str<<std::endl; } // struct steady_clock { // wraps QueryPerformanceCounter // using rep = long long; // using period = nano; // using duration = nanoseconds; // using time_point = chrono::time_point<steady_clock>; // static constexpr bool is_steady = true; // _NODISCARD static time_point now() noexcept { // get current time // const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot // const long long _Ctr = _Query_perf_counter(); // static_assert(period::num == 1, "This assumes period::num == 1."); // // Instead of just having "(_Ctr * period::den) / _Freq", // // the algorithm below prevents overflow when _Ctr is sufficiently large. // // It assumes that _Freq * period::den does not overflow, which is currently true for nano period. // // It is not realistic for _Ctr to accumulate to large values from zero with this assumption, // // but the initial value of _Ctr could be large. // const long long _Whole = (_Ctr / _Freq) * period::den; // const long long _Part = (_Ctr % _Freq) * period::den / _Freq; // return time_point(duration(_Whole + _Part)); // } // }; // using high_resolution_clock = steady_clock; // } // namespace chrono //計時器 steady_clock 類相當(dāng)于秒表,操作系統(tǒng)只要啟動就會進(jìn)行時間的累加,常用于耗時的統(tǒng)計(精確到納秒) 。 void Func3(){ //靜態(tài)成員函數(shù)std::chrono::steady_clock::now()獲取時間的開始點 std::chrono::time_point<std::chrono::steady_clock> start=std::chrono::steady_clock::now(); //auto start=std::chrono::steady_clock::now(); //執(zhí)行一些代碼,消耗時間 std::vector<std::string> vec1{"banana","apple","pear"}; std::for_each(vec1.begin(),vec1.end(),[&vec1](std::string str){ std::cout<<str<<" "; }); std::cout<<std::endl; //靜態(tài)成員函數(shù)std::chrono::steady_clock::now()獲取時間的結(jié)束點 auto end=std::chrono::steady_clock::now(); //計算消耗的時間,單位是納秒 auto dt=end-start; std::cout<<"耗時: "<<dt.count()<<"納秒 ("<<(double)dt.count()/(1000*1000*1000)<<"秒) "<<std::endl; } int main(int argc,char* argv[]){ Func1(); Func2(); Func3(); return 0; }
輸出結(jié)果:
PS D:\時間操作 chrono 庫\bin\Debug> .\main.exe
c1==c2
c1==c3
c2==c3
c1= 1
c2= 60
c3= 3600
c4= 3600000
1
1000
1000000
1000000000
2023-01-04 22:32:43
2023-01-04
22:32:43
2023-01-04 22:32:43
banana apple pear
耗時: 733400納秒 (0.0007334秒)
PS D:\時間操作 chrono 庫\bin\Debug>
到此這篇關(guān)于C++11計時器:chrono庫介紹的文章就介紹到這了,更多相關(guān)C++ chrono計時器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言宏定義結(jié)合全局變量的方法實現(xiàn)單片機(jī)串口透傳模式
今天小編就為大家分享一篇關(guān)于C語言宏定義結(jié)合全局變量的方法實現(xiàn)單片機(jī)串口透傳模式,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-12-12C++實現(xiàn)選擇排序(selectionSort)
這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)選擇排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-04-04構(gòu)造函數(shù)不能聲明為虛函數(shù)的原因及分析
構(gòu)造函數(shù)不需要是虛函數(shù),也不允許是虛函數(shù),因為創(chuàng)建一個對象時我們總是要明確指定對象的類型,盡管我們可能通過實驗室的基類的指針或引用去訪問它但析構(gòu)卻不一定,我們往往通過基類的指針來銷毀對象2013-10-10C語言學(xué)習(xí)之條件和?if...else語句詳解
這篇文章主要給大家介紹了C語言中的條件和?if...else語句,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-12-12C語言實現(xiàn)可保存的動態(tài)通訊錄的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實現(xiàn)一個簡單的可保存的動態(tài)通訊錄,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定幫助,需要的可以參考一下2022-07-07