對Linux系統中的時鐘和時間的探討

概要 shell

1)介紹Linux系統中時鐘的基本概念 ide

2)探討hwclock命令的工做方式。 ui

3)系統啓動過程當中Linux系統對系統時鐘和硬件時鐘的同步。 this

主要術語和背景知識 spa

UTC: Coordinated Universal Time, 一種是件標準,用以規範世界各地的時間。 操作系統

Time Zone: 時區,表示方式是:UTC-xx:xx, UTC+xx:xx。好比中國的時區表示是:UTC+08:00. rest

其餘一些相關術語,好比CST,DST等,咱們並不須要關心。 code


典型Linux對時鐘和時間的管理 orm

一個典型的Linux系統主要有兩種時鐘:系統時鐘(System Clock)和硬件時鐘(Hardware Clock)。 ip

硬件時鐘獨立運行於操做系統以外,有本身的電源供給,即便當系統關機時,它也依然在跑。Hardware Clock有時也叫BIOS Clock, CMOS Clock, RTC 等。可是隻有hardware clock這個詞彙不容易引發誤解。

系統時鐘就是由操做系統維護的一個時鐘。在Linux系統中,是由kernel維護,由timer的中斷進行驅動的一個時鐘(由於它是由計時器的中斷驅動的,因此能夠認爲是一個軟件時鐘)。

有兩個時鐘,就須要有同步。這個同步功能由hwclock來實現。在此僅做簡要介紹,詳情請查詢手冊(man hwclock).

hwclock在各個系統上的工做方式可能並不同,可是,在大多數狀況下,它經過訪問/dev/rtc來進行硬件時鐘的控制。在先行的發行版上,/dev/rtc不少時候是一個symlink,指向/dev/rtcX。影響hwclock工做的還有兩個因素,一個是TZ環境變量,一個是/etc下的配置文件(這個文件位置不一,也可能沒有,要看系統)。

一個典型的Linux系統,對時間的同步會自動發生在系統啓動和系統關閉的時候。系統啓動時,將Hardware Clock中的內容同步到System Clock;系統關閉時,將System Clock中的內容同步到Hardware Clock。固然,這種同步也能夠本身手動進行,或者利用腳本進行(本身編寫的,或者該版本系統中自帶的)。

以下是一個典型的啓動和關閉系統時,對系統時鐘和硬件時鐘進行同步的腳本,一般存在於/etc/init.d/目錄下。

#!/bin/sh
### BEGIN INIT INFO
# Provides:          hwclock
# Required-Start:    
# Required-Stop:     $local_fs
# Default-Start:     S
# Default-Stop:      0 6
# Short-Description: Set system clock
# Description:       Set system clock to hardware clock, according to the UTC
#                    setting in /etc/default/rcS (see also rcS(5)).
### END INIT INFO
#
# WARNING:      If your hardware clock is not in UTC/GMT, this script
#               must know the local time zone. This information is
#               stored in /etc/localtime. This might be a problem if
#               your /etc/localtime is a symlink to something in
#               /usr/share/zoneinfo AND /usr isn't in the root
#               partition! The workaround is to define TZ either
#               in /etc/default/rcS, or in the proper place below.

[ ! -x /sbin/hwclock ] && exit 0

. /etc/default/rcS
[ "$UTC" = "yes" ] && tz="--utc" || tz="--localtime"

case "$1" in
        start)
                if [ "$VERBOSE" != no ]
                then
                        echo "System time was `date`."
                        echo "Setting the System Clock using the Hardware Clock as reference..."
                fi

                if [ "$HWCLOCKACCESS" != no ]
                then
                        if [ -z "$TZ" ]
                        then
                           hwclock $tz --hctosys
                        else
                           TZ="$TZ" hwclock $tz --hctosys
                        fi
                fi

                if [ "$VERBOSE" != no ]
                then
                        echo "System Clock set. System local time is now `date`."
                fi
                ;;
        stop|restart|reload|force-reload)
                #
                # Updates the Hardware Clock with the System Clock time.
                # This will *override* any changes made to the Hardware Clock.
                #
                # WARNING: If you disable this, any changes to the system
                #          clock will not be carried across reboots.
                #
                if [ "$VERBOSE" != no ]
                then
                        echo "Saving the System Clock time to the Hardware Clock..."
                fi
                if [ "$HWCLOCKACCESS" != no ]
                then
                        hwclock $tz --systohc
                fi
                if [ "$VERBOSE" != no ]
                then
                        echo "Hardware Clock updated to `date`."
                fi
                exit 0
                ;;
        show)
                if [ "$HWCLOCKACCESS" != no ]
                then
                        hwclock $tz --show
                fi
                ;;
        *)
                echo "Usage: hwclock.sh {start|stop|show|reload|restart}" >&2
                echo "       start sets kernel (system) clock from hardware (RTC) clock" >&2
                echo "       stop and reload set hardware (RTC) clock from kernel (system) clock" >&2
                exit 1
                ;;
esac


hwclock 和 date 命令中--utc選項

這兩個命令雖然都有--utc選項,可是其含義是不一樣的。首先來看一段命令和結果。

chenqi@chenqi-OptiPlex-760:/etc/default$ date
Wed Oct 31 16:00:23 CST 2012
chenqi@chenqi-OptiPlex-760:/etc/default$ date --utc
Wed Oct 31 08:00:24 UTC 2012
chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --localtime -r
Wed 31 Oct 2012 08:00:30 AM CST  -0.594038 seconds
chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --utc -r
Wed 31 Oct 2012 04:00:37 PM CST  -0.937780 seconds
由上可見date --utc獲得的時間和hwclock --localtime獲得的時間一致,而date獲得的時間和hwclock --utc獲得的時間一致。這一點,容易讓人困擾。

實際上,date命令中--utc選項表示「對標準UTC時間進行操做」,因此date --utc是輸出當前的標準UTC時間;而hwclock中--utc選項的意思是,此次操做要考慮時區上的換算,好比,若是是讀取hardware clock的話,那麼讀出的數據(從本地讀出的時間),要考慮到時區,換算出當前時區的時間後,再作輸出。同理,--localtime表示不用進行時區上的考慮和換算,讀出什麼,就輸出什麼。

由此,上面的困擾就比較容易解釋了,hardware clock存儲的時UTC標準時間,因此用--localtime去讀取,獲得的就是標準UTC時間,即和date --utc一致。另一種狀況就是考慮了時區換算,道理同樣。


參考材料

hwclock manual

date manual

http://en.wikipedia.org/wiki/Time_zone

相關文章
相關標籤/搜索