对Linux系统中的时钟和时间的探讨


对Linux系统中的时钟和时间的探讨
 
概要
1)介绍Linux系统中时钟的基本概念
2)探讨hwclock命令的工作方式。
3)系统启动过程中Linux系统对系统时钟和硬件时钟的同步。
  www.2cto.com  
主要术语和背景知识
 
UTC: Coordinated Universal Time, 一种是件标准,用以规范世界各地的时间。
Time Zone: 时区,表示方式是:UTC-xx:xx, UTC+xx:xx。比如中国的时区表示是:UTC+08:00.
 
其他一些相关术语,比如CST,DST等,我们并不需要关心。
 
典型Linux对时钟和时间的管理
 
一个典型的Linux系统主要有两种时钟:系统时钟(System Clock)和硬件时钟(Hardware Clock)。
  www.2cto.com  
硬件时钟独立运行于操作系统之外,有自己的电源供给,即使当系统关机时,它也依然在跑。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/目录下。
01
#!/bin/sh
02
### BEGIN INIT INFO
03
# Provides:          hwclock
04
# Required-Start:   
05
# Required-Stop:     $local_fs
06
# Default-Start:     S
07
# Default-Stop:      0 6
08
# Short-Description: Set system clock
09
# Description:       Set system clock to hardware clock, according to the UTC
10
#                    setting in /etc/default/rcS (see also rcS(5)).
11
### END INIT INFO
12
#
13
# WARNING:      If your hardware clock is not in UTC/GMT, this script
14
#               must know the local time zone. This information is
15
#               stored in /etc/localtime. This might be a problem if
16
#               your /etc/localtime is a symlink to something in
17
#               /usr/share/zoneinfo AND /usr isn't in the root
18
#               partition! The workaround is to define TZ either
19
#               in /etc/default/rcS, or in the proper place below.
20
 
21
[ ! -x /sbin/hwclock ] && exit 0
22
 
23
. /etc/default/rcS
24
[ "$UTC" = "yes" ] && tz="--utc" || tz="--localtime"
25
 
26
case "$1" in
27
        start)
28
                if [ "$VERBOSE" != no ]
29
                then
30
                        echo "System time was `date`."
31
                        echo "Setting the System Clock using the Hardware Clock as reference..."
32
                fi
33
 
34
                if [ "$HWCLOCKACCESS" != no ]
35
                then
36
                        if [ -z "$TZ" ]
37
                        then
38
                           hwclock $tz --hctosys
39
                        else
40
                           TZ="$TZ" hwclock $tz --hctosys
41
                        fi
42
                fi
43
 
44
                if [ "$VERBOSE" != no ]
45
                then
46
                        echo "System Clock set. System local time is now `date`."
47
                fi
48
                ;;
49
        stop|restart|reload|force-reload)
50
                #
51
                # Updates the Hardware Clock with the System Clock time.
52
                # This will *override* any changes made to the Hardware Clock.
53
                #
54
                # WARNING: If you disable this, any changes to the system
55
                #          clock will not be carried across reboots.
56
                #
57
                if [ "$VERBOSE" != no ]
58
                then
59
                        echo "Saving the System Clock time to the Hardware Clock..."
60
                fi
61
                if [ "$HWCLOCKACCESS" != no ]
62
                then
63
                        hwclock $tz --systohc
64
                fi
65
                if [ "$VERBOSE" != no ]
66
                then
67
                        echo "Hardware Clock updated to `date`."
68
                fi
69
                exit 0
70
                ;;
71
        show)
72
                if [ "$HWCLOCKACCESS" != no ]
73
                then
74
                        hwclock $tz --show
75
                fi
76
                ;;
77
        *)
78
                echo "Usage: hwclock.sh {start|stop|show|reload|restart}" >&2
79
                echo "       start sets kernel (system) clock from hardware (RTC) clock" >&2
80
                echo "       stop and reload set hardware (RTC) clock from kernel (system) clock" >&2
81
                exit 1
82
                ;;
83
esac
 
hwclock 和 date 命令中--utc选项
 
这两个命令虽然都有--utc选项,但是其含义是不同的。首先来看一段命令和结果。
 
1
chenqi@chenqi-OptiPlex-760:/etc/default$ date
2
Wed Oct 31 16:00:23 CST 2012
3
chenqi@chenqi-OptiPlex-760:/etc/default$ date --utc
4
Wed Oct 31 08:00:24 UTC 2012
5
chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --localtime -r
6
Wed 31 Oct 2012 08:00:30 AM CST  -0.594038 seconds
7
chenqi@chenqi-OptiPlex-760:/etc/default$ sudo hwclock --utc -r
8
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
 

相关内容

    暂无相关文章