1 Linux時間系統
電腦最基本的時間單元是刻度,例如取指令、執行指令、存取記憶體等。時間系統是電腦系統非常重要的組成部分,特別是對於Unix類分時系統尤為重要。時間系統主要任務是維持系統時間並且防止某個進程獨佔CPU及其他資源,也就是驅動進程的調度。
1.1 時鐘硬體
大部分PC機中有兩個時鐘源,他們分別叫做RTC和OS作業系統)時鐘。RTCReal Time Clock,系統時鐘)也叫做CMOS時鐘,它是PC主機板上的一塊晶片,它靠電池供電,即使系統斷電,也可以維持日期和時間。由於它獨立於作業系統,所以也被稱為硬體時鐘,它為整個電腦提供一個計時標準,是最原始最底層的時鐘資料。
Linux只用RTC來獲得時間和日期;然而,通過作用於/dev/rtc裝置檔案,也允許進程對RTC編程。通過執行/sbin/clock系統程式,系統管理員可以配置時鐘。
OS時鐘產生於PC主板上的定時/計數晶片,由作業系統控制這個晶片的工作,OS時鐘的基本單位就是該晶片的計數周期。在開機時作業系統取得RTC中的時間資料來初始化OS時鐘,然後通過計數晶片的向下計數形成了OS時鐘,它更應該被稱為一個計數器。OS時鐘只在開機時才有效,而且完全由作業系統控制,所以也被稱為軟時鐘或系統時鐘。下面我們重點描述OS時鐘的產生。
OS時鐘輸出脈衝訊號,接到中斷控制器上,產生中斷訊號,觸發後面要講的時鐘中斷,由時鐘中斷服務程式維持OS時鐘的正常工作。
1.2 時鐘運作機制
RTC和OS時鐘之間的關係通常也被稱作作業系統的時鐘運作機制。一般來說,RTC是OS時鐘的時間基準,作業系統通過讀取RTC來初始化OS時鐘,此後二者保持同步運行,共同維持著系統時間。保持同步運行是什麼意思呢?就是指作業系統運行過程中,每隔一個固定時間會重新整理或校正RTC中的資訊。
圖2 時鐘運作機制
我們可以看到,RTC處於最底層,提供最原始的時鐘資料。OS時鐘建立在RTC之上,初始化完成後將完全由作業系統控制,和RTC脫離關係。作業系統通過OS時鐘提供給應用程式所有和時間有關的服務。
1.3 Linux時間基準
以上我們瞭解了RTC系統時鐘、硬體時鐘)和OS時鐘系統時鐘、軟時鐘)。下面我們具體描述OS時鐘。OS時鐘是由可程式化定時/計數器產生的輸出脈衝觸發中斷而產生的。輸出脈衝的周期叫做一個“時鐘滴答”。電腦中的時間是以時鐘滴答為單位的,每一次時鐘滴答,系統時間就會加1。作業系統根據當前時鐘滴答的數目就可以得到以秒或毫秒等為單位的其他時間格式。
定義“時間基準”的目的是為了簡化計算,這樣電腦中的時間只要表示為從這個時間基準開始的時鐘滴答數就可以了。“時間基準是由作業系統的設計者規定的。例如DOS的時間基準是1980年1月1日,Unix的時間基準是1970年1月1日上午12點,Linux的時間基準是1970年1月1日淩晨0點。
1.4 Linux的時間系統
OS時鐘記錄的時間也就是通常所說的系統時間。系統時間是以“時鐘滴答”為單位的,而時鐘中斷的頻率決定了一個時鐘滴答的長短,例如每秒有100次時鐘中斷,那麼一個時鐘滴答的就是10毫秒記為10ms),相應地,系統時間就會每10ms增1。
Linux中用全域變數jiffies表示系統自啟動以來的時鐘滴答數目。在/kernel/time.c中定義如下:
unsigned long volatile jiffies
在jiffies基礎上,Linux提供了如下適合人們習慣的時間格式,在/include/linux/time.h中定義如下:
struct timespec {/* 這是精度很高的表示*/
long tv_sec; /* 秒 second) */
long tv_nsec; /* 納秒:十億分之一秒 nanosecond)*/
};
struct timeval {/* 普通精度*/
int tv_sec; /* 秒*/
int tv_usec; /* 微秒:百萬分之一秒microsecond)*/
};
struct timezone {/* 時區 */
int tz_minuteswest;/* 格林尼治時間往西方的時差 */
int tz_dsttime;/* 時間修正方式 */
};
tv_sec表示秒second),tv_usec表示微秒microsecond),tv_nsec表示納秒nanosecond)。定義tb_usec和tv_nsec的目的是為了適用不同的使用要求,不同的場合根據對時間精度的要求選用這兩種表示。另外,Linux還定義了用於表示更加符合福士習慣的時間表示:年、月、日。但是萬變不離其宗,所有的時間應用都是建立在jiffies基礎之上的。簡而言之,jiffies產生於時鐘中斷!
2 時鐘中斷