linux内核中测量时间的方法,Linux内核中获取时间函数do_gettimeofday
內核代碼能一直獲取一個當前時間的表示, 通過查看 jifies 的值. 常常地, 這個值只代表從最后一次啟動以來的時間, 這個事實對驅動來說無關, 因為它的生命周期受限于系統的 uptime. 如所示, 驅動可以使用 jiffies 的當前值來計算事件之間的時間間隔(例如, 在輸入驅動中從單擊中區分雙擊或者計算超時). 簡單地講, 查看 jiffies 幾乎一直是足夠的, 當你需要測量時間間隔. 如果你需要對短時間流失的非常精確的測量, 處理器特定的寄存器來幫忙了( 盡管它們帶來嚴重的移植性問題 ).
它是非常不可能一個驅動會需要知道墻上時鐘時間, 以月, 天, 和小時來表達的; 這個信息常常只對用戶程序需要, 例如 cron 和 syslogd. 處理真實世界的時間常常最好留給用戶空間, 那里的 C 庫提供了更好的支持; 另外, 這樣的代碼常常太策略相關以至于不屬于內核. 有一個內核函數轉變一個墻上時鐘時間到一個 jiffies 值, 但是:
#include
unsigned long mktime (unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec);
重復:直接在驅動中處理墻上時鐘時間往往是一個在實現策略的信號, 并且應當因此而被置疑.
雖然你不會一定處理人可讀的時間表示, 有時你需要甚至在內核空間中處理絕對時間. 為此, 輸出了 do_gettimeofday 函數. 當被調用時, 它填充一個 struct timeval 指針 -- 和在 gettimeofday 系統調用中使用的相同 -- 使用類似的秒和毫秒值. do_gettimeofday 的原型是:
#include
void do_gettimeofday(struct timeval *tv);
這段源代碼聲明 do_gettimeofday 有" 接近毫秒的精度", 因為它詢問時間硬件當前 jiffy 多大比例已經流失. 這個精度每個體系都不同, 但是, 因為它依賴實際使用中的硬件機制. 例如, 一些 m68knommu 處理器, Sun3 系統, 和其他 m68k 系統不能提供大于 jiffy 的精度. Pentium 系統, 另一方面, 提供了非常快速和精確的小于嘀噠的測量, 通過讀取本章前面描述的時戳計數器.
當前時間也可用( 盡管使用 jiffy 的粒度 )來自 xtime 變量, 一個 struct timespec 值. 不鼓勵這個變量的直接使用, 因為難以原子地同時存取這 2 個字段. 因此, 內核提供了實用函數 current_kernel_time:
#include
struct timespec current_kernel_time(void);
用來以各種方式獲取當前時間的代碼, 可以從由 O' Reilly 提供的 FTP 網站上的源碼文件的 jit ("just in time") 模塊獲得. jit 創建了一個文件稱為 /proc/currentime, 當讀取時, 它以 ASCII 碼返回下列項: 當前的 jiffies 和 jiffies_64 值, 以 16 進制數的形式. 如同 do_gettimeofday 返回的相同的當前時間. 由 current_kernel_time 返回的 timespec. 我們選擇使用一個動態的 /proc 文件來保持樣板代碼為最小 -- 它不值得創建一整個設備只是返回一點兒文本信息. 這個文件連續返回文本行只要這個模塊加載著; 每次 read 系統調用收集和返回一套數據, 為更好閱讀而組織為 2 行. 無論何時你在少于一個時鐘嘀噠內讀多個數據集, 你將看到 do_gettimeofday 之間的差別, 它詢問硬件, 并且其他值僅在時鐘嘀噠時被更新. 1、使用rtc設備,這個時鐘可以用于各種模式? 2、借鑒系統調用adjtimex? 這里使用第二種方式 系統調用adjtimex 一直跟下去,會發現最后調用? void do_gettimeofday(struct timeval *tv) 那么直接使用do_gettimeofday,能夠得到struct timeval struct timeval {? time_t tv_sec; /* seconds */? suseconds_t tv_usec; /* microseconds */? }; 那么就需要將這個tv_sec,即1970年開始至今的秒數轉換為年月日時分秒? 其實內核已經有這樣的函數? /*? * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.? */? void rtc_time_to_tm(unsigned long time, struct rtc_time *tm) 唯一的不足是轉換得到的是UTC時間,同北京時間差8小時。要想達到用戶態localtime()的效果,必須獲得/etc/localtime 中的時區信息。 示例代碼: #include ? #include ? #include /*添加到合適位置*/ struct timex ?txc;? struct rtc_time tm;? do_gettimeofday(&(txc.time));? rtc_time_to_tm(txc.time.tv_sec,&tm);? printk(“UTC time :%d-%d-%d %d:%d:%d /n”,tm.tm_year+1900,tm.tm_mon, tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
總結
以上是生活随笔為你收集整理的linux内核中测量时间的方法,Linux内核中获取时间函数do_gettimeofday的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Argus
- 下一篇: linux 内核空间占用cpu百分比过高