コンピューターにおける時間制御


コンピュータの時間制御の仕組みについて、基本を理解しようと思って調べてみた。
重要概念と仕組みを書いていく。

時間制御の大枠

  1. 起動時に、hardware clock から system clock を設定する。
  2. カーネルが system clock を正確に維持する。
  3. シャットダウン時に、system clock から hardware clock を設定する。

Hardware clock

名前の通り、ハードウェアのクロック。
Real Time Clock (RTC) や CMOS Clock とも言う。

年、月、日、時、分、秒を保持する。
2016年以降のみ、UEFI のファームウェアが time zone や夏時間使用の有無を保持できる。


hwclockコマンドで hardware clock を読み込む。

$ hwclock --show
2020-12-02 20:53:32.887578+09:00

time zone を考慮された現在時刻がでてきた。localtime で表示される。

次に hardware clock を system clock に同期する。

# hwclock --systohc

これで hardware clock が調整された。
同時に/etc/adjtime/というファイルが更新される。

$ cat /etc/adjtime
0.000000 1606910322 0.000000
1606910322
UTC

このファイルの詳細はhwclock(8)の man ページのThe Adjtime Fileというところに書いてある。
たった3行のファイルなのだが、その中に hardware clock が調整された最新の時刻が書かれている。これが更新されるようである。

System clock

時刻、タイムゾーン、(必要な場合は) 夏時間をトラックする。
Linux カーネルによって、1970/1/1 00:00:00 からの秒数の数字で管理/計算されている。
初期値は hardware clock から計算され、起動後は hardware clock から独立して動く。


timedatectlコマンドで system clock を読み込む。

$ timedatectl status
               Local time: Wed 2020-12-02 21:23:19 JST
           Universal time: Wed 2020-12-02 12:23:19 UTC
                 RTC time: Wed 2020-12-02 12:23:19    
                Time zone: Asia/Tokyo (JST, +0900)    
System clock synchronized: no                         
              NTP service: inactive                   
          RTC in local TZ: no

色々でてきたが比較的読みやすい。
RTC は real-time clock の略であり、つまり hardware clock。
RTC in local TZ: noはそのまま、hardware clock が local time zone を使っておらず、UTC 時間ということだろう。

Time standard (時刻標準?)

2つの time standard がある。
UTC と localtime。

hardware clock がどちらの standard を使うかは OS が決定する。
例えば、デフォルトでは Windows は localtime を使い、macOS は UTC を使う。
だから複数の OS がPCに入ってた場合、コンフリクトが起こることがあるのだそう。こわい。

Time zone

システム全体の local time の time zone は、/etc/localtimeファイルが定義している。
このファイルは/usr/share/zoneinfo/XXX/XXXファイルのシンボリックリンクで、例えばAsia/Tokyoの time zone を使用する場合は、下記のように設定する。

$ ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

なお下記のようなコマンドを使っても自動で time zone を設定できる。
実行される内容は上と同じ。

$ timedatectl set-timezone Asia/Tokyo

Time skew (時間のずれ)

完全に正確な時計というものはない。電子時計は一貫した不正確さを維持する。
この不正確さを time skew とか time drift と呼ぶ。

hardware clock に新しく時間が設定されると、drift 値が/etc/adjtimeファイルに書き込まれる。
1行目1番目の値が drift rate。

$ cat /etc/adjtime
0.000000 1606920696 0.000000
1606920696
UTC

この値は以下の要素から計算される。

  • 前回の hardware clock 設定時刻 (/etc/adjtimeの1行目2番目の数字)
  • 前回設定時の drift rate
  • 新しく設定される time value と、そのときに hardware clock が保持していた time value の差異

この drift rate を保持しておくことでhwclock --adjustコマンドで hardware clock を正確に調節できる。
またhwclockデーモンが動いている場合は、シャットダウン時に同じことが実行される。

もしこの drift value が大きい値になった場合、なにか想定外のことが起きている。
例えば、不正確な時間を hardware clock に設定してしまったり、または time standard の同期がおかしかったりする。

おわり

コンピューターの時間制御の基本について理解できたかも。

なおこの記事のほとんどは、参照欄に載せた Arch wiki による。
とてもすばらしい wiki だと思う。

なにか間違ったことを書いていたら指摘していただけるとありがたいです。

参照

Arch wiki
https://wiki.archlinux.org/index.php/System_time

man ページたち

  • hwclock(8)
  • timedatectl(1)
  • localtime(5)