Linux開發--相對時間

今天,再次碰到一個由於系統時間調整導致的bug。不得不再次查找完美的問題解決方案。

雖然,按道理來說,系統時間進行重置之後,一些應用程序的行爲出現異常是合乎情理,並且是可以被理解並接受的,最重要的是這樣的問題都可以通過重新啓動操作系統來解決(微軟大哥解決問題之道),但是,對於軟件開發人員來說,應該儘量避免非必要的重啓。對自己嚴格要求點兒似乎沒什麼過錯!?

對絕對時間的依賴似乎不怎麼容易擺脫,但是我們的應用程序又有多少是嚴格依賴於系統的絕對時間呢?很多時候,我們只要求能夠求出時間間隔就可以了。時間間隔實際上是可以拋開絕對時間求得的,我們可以採用相對於某個時間點的相對時鐘來計時,比如說系統啓動時間。

自然地,我們就想到了proc僞文件系統下的/proc/uptime文件。通過讀這個文件,我們能夠獲得相對於系統啓動時刻的相對時間,其精度爲百分之一秒:

[xiaosuo@Ulard-iolo ~]$ cat /proc/uptime
4057840.13 3326432.09

讀/proc/uptime簡單易行,也適合shell操作,但是只爲了一個簡單的相對時間就進行三次系統調用(open, read, close)和一次字符串解析,這樣的複雜度顯然不能滿足吹毛求疵的我這種人的非禮要求。

聯想到Linux內核空間的精度爲(1/HZ)秒的計時變量jiffies,如果有哪個系統調用把它導到用戶空間,其效率可見是比較高的,再次扒到了系統調用times:

       #include <sys/times.h>

       clock_t times(struct tms *buf);


times的返回值是相對於某個固定時刻的時間。這個固定時刻,在2.4內核及其之前是系統啓動,以後就改成了系統啓動((2^32/HZ) - 300)秒之前(這個對jiffies初始值的改動是爲了使Linux內核能夠儘快地暴露有關jiffies變量回卷的bug)。所以,應用程序不要依賴於這個開始時刻,如果非要依賴,可以通過其他的方式先得到系統的啓動時間,然後與其做差值,求得偏移量,以後就能參考這個偏差求得系統的啓動時間。這個函數的返回值clock_t的單位爲(1/sysconf(_SC_CLK_TCK);)秒(sysconf(_SC_CLK_TCK)通常爲100),並且clock_t可能溢出(在2.6內核的Linux系統上,系統啓動5分鐘就會溢出),所以需要特別小心。

times雖然高效,但是他的精度還是略顯不夠,所以我繼續挖掘。最終找到了clock_gettime這個系統調用:

        #include <time.h>

       int clock_getres(clockid_t clk_id, struct timespec *res);
       int clock_gettime(clockid_t clk_id, struct timespec *tp);


clk_id爲CLOCK_MONOTONIC的單調時鐘能夠滿足我們的需求,並且它的精度一般都會很高,略微地瀏覽了一遍它的內核實現,也較爲輕量,可謂完美!

以上介紹的三種獲得相對時間的方法的詳細用法,還請各位在需要的時候去翻看其手冊頁
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章