C++中Boost.Chrono時(shí)間庫(kù)的使用方法
前言
大家應(yīng)該都有所體會(huì),時(shí)鐘這個(gè)東西在程序中扮演者重要的角色,在系統(tǒng)編程的時(shí)候睡眠、帶超時(shí)的等待、帶超時(shí)的條件變量、帶超時(shí)的鎖都會(huì)用到,但是往往對(duì)特定系統(tǒng)依賴性很大,感覺(jué)即使不考慮系統(tǒng)的跨平臺(tái)性,如果能使用一個(gè)穩(wěn)定的接口,同時(shí)如果能夠方便的對(duì)時(shí)刻、時(shí)段等進(jìn)行相關(guān)的操作和運(yùn)算,將是再好不過(guò)的了。
在boost庫(kù)中和時(shí)間相關(guān)的庫(kù)有Boost.DateTime和Boost.Chrono,前者專注于時(shí)間時(shí)刻以及本地化相關(guān)的內(nèi)容,而后者主要是時(shí)刻、時(shí)長(zhǎng)和時(shí)間的計(jì)算等內(nèi)容。當(dāng)然,C++11標(biāo)準(zhǔn)已經(jīng)支持std::chrono了,但是為了兼容老編譯系統(tǒng)現(xiàn)在很多C++庫(kù)和程序都使用boost.chrono作為時(shí)間類庫(kù)(還有的原因就是std::chrono沒(méi)有收錄boost.chrono的所有功能,比如統(tǒng)計(jì)CPU使用時(shí)間、自定義時(shí)間輸出格式等),不過(guò)比較可惜的是即便使用boost::chrono作為權(quán)宜之計(jì),也需要boost-1.47版本之上才行,而現(xiàn)在比較舊的發(fā)行版需要升級(jí)boost庫(kù)才可以使用。想想現(xiàn)在RHEL-6.x仍然被大規(guī)模的部署,而且RedHat要為這貨提供長(zhǎng)達(dá)十年的技術(shù)支持,真不知道啥時(shí)候才能順順利利的享受C++11……
Boost.Chrono的時(shí)間類型分為duration和time_point,也就是時(shí)長(zhǎng)和時(shí)刻兩類,很多概念和接口都是圍繞這兩個(gè)維度去定義和實(shí)現(xiàn)的。
一、Clock
clock是Boost.Chrono中的重要概念,而且這些clock都包含一個(gè)now()的成員函數(shù),用于返回當(dāng)前的time_point。Boost.Chrono包含的clock類型有:
(1) chrono::system_clock 代表系統(tǒng)時(shí)間,比如電腦上顯示的當(dāng)前時(shí)間,其特點(diǎn)是這個(gè)時(shí)間可以被用戶手動(dòng)設(shè)置更新,所以這個(gè)時(shí)鐘是可以和外部時(shí)鐘源同步的。這個(gè)時(shí)鐘還有一個(gè)to_time_t()成員函數(shù),用于返回自1970.1.1開(kāi)始到某個(gè)時(shí)間點(diǎn)所經(jīng)過(guò)的秒數(shù),數(shù)據(jù)類型是std::time_t。這種時(shí)鐘通常用來(lái)轉(zhuǎn)換成日歷時(shí)間使用。
(2) chrono::steady_clock 其特點(diǎn)是時(shí)間是單調(diào)增長(zhǎng)的,后一個(gè)時(shí)刻訪問(wèn)得到的時(shí)間點(diǎn)肯定比之前時(shí)刻得到的時(shí)間點(diǎn)要晚,即使我們手動(dòng)將系統(tǒng)時(shí)間向前調(diào)整了也不會(huì)改變這個(gè)時(shí)鐘穩(wěn)步向前推行累計(jì),其也被稱為monotonic time,該時(shí)鐘是均勻增長(zhǎng)且不能被調(diào)整,其特性對(duì)于很多不允許時(shí)間錯(cuò)亂的系統(tǒng)是十分重要的。chrono::steady_clock通常是基于系統(tǒng)啟動(dòng)時(shí)間來(lái)計(jì)時(shí)的,而且常常用來(lái)進(jìn)行耗時(shí)、等待等工作使用。
(3) chrono::high_resolution_clock 依賴于系統(tǒng)實(shí)現(xiàn),通常是上面兩種時(shí)鐘的某個(gè)宏定義,取決于哪個(gè)時(shí)鐘源更為的精確,所以其輸出也決定于取決于上面哪個(gè)clock來(lái)實(shí)現(xiàn)的。
(4) chrono::process_real_cpu_clock 表示自進(jìn)程啟動(dòng)以來(lái)使用的CPU時(shí)間,而這個(gè)數(shù)據(jù)也可以通過(guò)使用std::clock()來(lái)獲得。chrono::process_user_cpu_clock、boost::chrono::process_system_cpu_clock表示自進(jìn)程啟動(dòng)以來(lái),在用戶態(tài)、內(nèi)核態(tài)所花費(fèi)的時(shí)間,而所有的這些事件可以通過(guò)chrono::process_cpu_clock來(lái)獲得,他返回上面所有時(shí)間組成的一個(gè)tuple結(jié)構(gòu)。
(5) chrono::thread_clock 返回基于線程統(tǒng)計(jì)的花費(fèi)時(shí)間,而且不區(qū)分用戶態(tài)、內(nèi)核態(tài)的時(shí)間。
二、time_point
time_point代表時(shí)間點(diǎn),其等價(jià)于某個(gè)時(shí)刻(clock)+duration的結(jié)果,同時(shí)兩個(gè)time_point做減法也可以得到一個(gè)duration。time_point常見(jiàn)的描述為:3分鐘之后、2038年1月1日10:32:23、定時(shí)器啟動(dòng)后的20ms……
上面的clock都有一個(gè)now()成員函數(shù),其返回的就是chrono::time_point類型。這個(gè)類型使用一個(gè)模板來(lái)實(shí)現(xiàn)的,所以其實(shí)際類型極度依賴于所選擇的時(shí)鐘源。
Boost.Chrono有一個(gè)chrono::time_point_cast轉(zhuǎn)換函數(shù),可以顯式從高粒度向低粒度對(duì)time_point進(jìn)行轉(zhuǎn)換。
chrono::process_real_cpu_clock::time_point p = chrono::process_real_cpu_clock::now(); std::cout << chrono::time_point_cast<minutes>(p) << '\n';
三、duration
關(guān)于時(shí)長(zhǎng),chrono::duration也是一個(gè)模板類型,其第一個(gè)模板參數(shù)表明存儲(chǔ)所用的數(shù)據(jù)類型(int、long、double等),第二個(gè)模板參數(shù)表示ratio(比如24、60、1000等)。為了方便用戶的使用,Boost.Chrono提供了duration常用的六種時(shí)間類型,且他們都用一個(gè)足夠大的整數(shù)進(jìn)行內(nèi)部保存,其計(jì)量值可以用count()成員函數(shù)得到:
chrono::nanoseconds、chrono::milliseconds、chrono::microseconds、chrono::seconds、chrono::minutes、chrono::hours,而且為這些類型都重載了計(jì)算操作符:+、-、<等,方便時(shí)間的計(jì)算和比較。文檔說(shuō)傳統(tǒng)的Boost.DateTime是用繼承實(shí)現(xiàn)的,相比而言Boost.Chrono更加的簡(jiǎn)潔高效,而且和前者保持了一致的接口。
chrono::steady_clock::time_point start = chrono::steady_clock::now(); ... chrono::duration<double> sec = chrono::steady_clock::now() - start; std::cout << "we took " << sec.count() << " seconds\n"; auto go = chrono::steady_clock::now() + chrono::nanoseconds(500); while (chrono::steady_clock::now() < go) ... ;
上面的六種time_point類型表示的維度不一,粗粒度的時(shí)長(zhǎng)肯定能用細(xì)粒度的類型表示,反之則可能丟失精度,所以需要使用chrono::duration_cast()函數(shù)做顯式的轉(zhuǎn)換。
可能上面六種類型的時(shí)間不咋的,但重點(diǎn)是現(xiàn)在boost::chrono被廣為使用在boost的其他庫(kù)里面,比如我們看一個(gè)條件變量的帶超時(shí)等待的原型:
template< typename Clock, typename Duration >
cv_status wait_until( std::unique_lock< mutex > & lk,
std::chrono::time_point< Clock, Duration > const& abs_time);
template< typename Rep, typename Period >
cv_status wait_for( std::unique_lock< mutex > & lk,
std::chrono::duration< Rep, Period > const& rel_time);
這就意味著我們可以直接將chrono::minutes{2}這樣的duration對(duì)象丟給這個(gè)函數(shù)就好了,創(chuàng)建任意精度的時(shí)長(zhǎng)都很方便,而不用像以前一樣關(guān)注函數(shù)接口有人用seconds、有人用milliseconds、有人用timeval了。
現(xiàn)在boost庫(kù)和標(biāo)準(zhǔn)庫(kù)中,基于時(shí)間段超時(shí)的函數(shù)都具有for后綴,而基于時(shí)間點(diǎn)超時(shí)的變量具有until后綴,比如this_thread::sleep_for()和this_thread::sleep_until()類似的還有:wait、try_lock、unique_lock用于條件變量、mutex互斥、unique_lock操作。
四、自定義格式的時(shí)間輸出
通過(guò)time_fmt()可以對(duì)時(shí)刻進(jìn)行格式化輸出,使用的時(shí)候需要包含頭文件。
time_fmt(boost::chrono::timezone::local, "%H:%M:%S"); time_fmt(boost::chrono::timezone::utc, "%H:%M:%S");
參考
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- C++日期與時(shí)間 chrono庫(kù)介紹及使用教程
- C/C++時(shí)間庫(kù)chrono的使用總結(jié)
- 深入理解C++中std::chrono庫(kù)的使用
- 關(guān)于C++使用std::chrono獲取當(dāng)前秒級(jí)/毫秒級(jí)/微秒級(jí)/納秒級(jí)時(shí)間戳問(wèn)題
- c++11 chrono全面解析(最高可達(dá)納秒級(jí)別的精度)
- C++11中的時(shí)間庫(kù)std::chrono(引發(fā)關(guān)于時(shí)間的思考)
- C++算法計(jì)時(shí)器的實(shí)現(xiàn)示例
- C++實(shí)現(xiàn)統(tǒng)計(jì)代碼運(yùn)行時(shí)間計(jì)時(shí)器的簡(jiǎn)單實(shí)例
- C++11計(jì)時(shí)器之chrono庫(kù)簡(jiǎn)介
相關(guān)文章
C語(yǔ)言中字符串的內(nèi)存地址操作的相關(guān)函數(shù)簡(jiǎn)介
這篇文章主要介紹了C語(yǔ)言中字符串的內(nèi)存地址操作的相關(guān)函數(shù),包括bcopy()函數(shù)和bzero()函數(shù)以及bcmp()函數(shù),需要的朋友可以參考下2015-08-08
vscode 配置 C/C++ 編譯環(huán)境的詳細(xì)圖文教程
這篇文章主要介紹了vscode 配置 C/C++ 編譯環(huán)境的詳細(xì)教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
C語(yǔ)言單鏈隊(duì)列的表示與實(shí)現(xiàn)實(shí)例詳解
這篇文章主要介紹了C語(yǔ)言單鏈隊(duì)列的表示與實(shí)現(xiàn),對(duì)于研究數(shù)據(jù)結(jié)構(gòu)與算法的朋友來(lái)說(shuō)很有參考借鑒價(jià)值,需要的朋友可以參考下2014-07-07
C語(yǔ)言實(shí)現(xiàn)順序表的順序查找和折半查找
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)順序表的順序查找和折半查找,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06

