linux時間函數
『壹』 linux時間的獲取與使用
Linux系統中的時間包含兩種形式,日歷時間和進程時間。日歷時間表示從1970年1月1日0點(UTC時間)以來的秒數累計值,通過time_t數據類型保存,最後轉換得到我們熟悉的24小時或12小時制時間。而進程時間,即CPU時間,衡量進程使用中央處理器資源的量,以時鍾滴答計算。
獲取日歷時間的函數time()返回時間戳,為從1970年1月1日0點到現在經歷的秒數,如返回值1533287924。為了獲得更高精度的時間,使用gettimeofday()和clock_gettime()函數。gettimeofday()函數用timeval結構體保存微秒精度的時間戳,clock_gettime()函數用timespec結構體保存納秒精度的時間戳。
將時間戳轉化為日/月/年的時間,使用tm結構體。通過gmtime()和localtime()函數將time_t類型的時間戳轉換為tm結構體表示的日期時間。固定格式列印時間,可以使用ctime()和asctime()函數,但這兩個函數已被標記為棄用。更安全的方法是採用strftime()函數,它支持自定義格式化輸出日期和時間。
在業務程序中,對比時間的先後通常通過時間戳進行,mktime()函數用於將struct tm結構體轉換為time_t的時間戳,便於比較和計算。但在轉換時需要注意,使用localtime()函數得到的時間戳是從1900年1月1日開始計算的,可能需要調整以得到准確結果。
Linux系統中的進程時間表示進程使用CPU的時間,分為用戶時間和內核時間兩部分。clock()函數提供了一個簡單的介面,返回值描述進程使用的總的CPU時間,計量單位為CLOCKS_PER_SEC。times()函數提供了更詳細的進程時間表示,返回值的計量單位由sysconf(SC_CLK_TCK)確定。
通過以上描述,我們可以清楚地理解Linux系統中時間的獲取與使用方法,以及不同函數之間的關系,為實際編程提供有力支持。
『貳』 雜談:Linux時間管理之gettimeofday實現
Linux的時間管理是一項核心功能,其中gettimeofday函數作為用戶態與內核交互的重要橋梁,其實現方式值得深入探討。一開始,許多人可能會以為gettimeofday直接調用系統調用,然而事實並非如此。實際上,glibc為用戶提供了一層封裝,通過調用內核提供的其他函數實現gettimeofday的功能。以glibc2.35為例,其在time目錄下的gettimeofday.c文件中實現了這一功能,它通過調用內核的__clock_gettime函數來獲取當前時間。進一步探索__clock_gettime函數的實現,我們發現其最終通過調用__clock_gettime64函數來完成時間獲取。
__clock_gettime64函數的實現位於glibc2.35/sysdeps/unix/sysv/linux/clock_gettime.c文件中。在函數實現過程中,我們關注到函數的實現邏輯中包含了一個分支,涉及到了一個叫做vdso(虛擬動態共享對象)的概念。vdso是一種優化機制,它利用內存映射技術將內核數據直接映射到用戶空間,從而避免了系統調用的開銷,極大地提高了性能。為了了解系統中支持vdso的系統調用,可以查閱相關文檔或使用特定命令進行查詢。
內核態方面,Linux通過周期定時器進行時間更新,其中tick_sched_timer函數在更新系統狀態時也參與時間維護。在update_vsyscall函數中,內核會更新vdso的數據結構,這表明即使在不考慮NOHZ情況的場景下,系統也支持正常的中斷調用以進行時間更新。
綜上所述,Linux的時間管理涉及內核與用戶態之間的復雜交互,其中gettimeofday函數的實現展示了這種交互的層次性和優化策略。從用戶態的glibc封裝到內核態的時間更新機制,每一個環節都體現了Linux在設計上的精妙與高效。對於深入理解Linux內核和系統編程而言,這些細節是不可忽視的。然而,要完全掌握這些內容,需要對glibc結構組織、vdso機制以及內核時間更新等概念有深入的理解。