UNIX時間は、UNIXを実行しているコンピューターで測定されます。
この答えは、世界標準時(UTC)、国際原子時(TAI)、およびSI秒が何であるかを知っていることを期待します。それらの説明は、UnixおよびLinux Stack Exchangeの範囲をはるかに超えています。 これは物理学または天文学スタック交換ではありません。
ハードウェア
コンピューターには、クロックとタイマーを駆動するさまざまな発振器が含まれています。正確には、アーキテクチャによってコンピューターごとに異なります。しかし、通常、そして非常に一般的な用語で:
- プログラム可能なインターバルタイマー(PIT)がどこかにあります。これは、指定された数の発振をカウントし、中央処理装置への割り込みをトリガーするようにプログラムできます。
- 中央処理装置には、実行される命令サイクルごとに1を単純にカウントするサイクルカウンターがあります。
非常に広い意味での動作理論
オペレーティングシステムカーネルは、PITを使用してティックを生成します。PITをフリーランに設定し、たとえば100分の1秒の時間間隔で適切な振動数をカウントし、割り込みを生成してから、カウントを自動的にリセットして再び実行します。これにはさまざまなバリエーションがありますが、本質的には、これによりティック割り込みが固定周波数で発生します。
ソフトウェアでは、カーネルはティックごとにカウンターをインクリメントします。そもそもPITをプログラムしたため、ティック周波数を知っています。したがって、1秒を構成するティックの数がわかります。これを使用して、秒をカウントするカウンターをいつインクリメントするかを知ることができます。後者は、カーネルの「UNIX Time」の考え方です。実際、独自のデバイスに任せた場合は、SI秒あたり1の割合で単純にカウントアップします。
これを複雑にしているのは4つのことで、これを非常に一般的な用語で説明します。
ハードウェアは完璧ではありません。Nヘルツの発振器周波数を持っているとデータシートに記載されているPITは、代わりに(たとえば)N .00002ヘルツの周波数を持っているかもしれませんが、明らかな結果があります。
このスキームは、CPUが1秒間に数百回目を覚まして変数の数値を増やすだけなので、電力管理との相互運用性は非常に低くなります。そのため、一部のオペレーティングシステムには、「ティックレス」設計と呼ばれるものがあります。PITがすべてのティックに対して割り込みを送信する代わりに、カーネルは(低レベルスケジューラから)スレッドクォンタムを実行せずに何ティックが通過するかを計算し、その多数のティックをカウントするようにPITをプログラムしますティック割り込みを発行する前の未来。次に、1ティックではなく、次のティック割り込みでNティックの経過を記録する必要があることを知っています。
アプリケーションソフトウェアには、カーネルの現在時刻を変更する機能があります。値をステップすることも、値をスルーすることもできます。回転には、秒カウンタをインクリメントするために通過する必要があるティックの数の調整が含まれます。そのため、秒カウンタは、とにかく SIごとに1つのレートでカウントする必要はありません。完璧なオシレーターを想定していてもです。ステッピングには、単に秒カウンターに新しい数値を書き込むだけです。これは通常、最後の秒が刻まれてから1 SI秒が経過するまで発生しません。
最新のカーネルは、秒をカウントするだけでなく、ナノ秒もカウントします。しかし、1ナノ秒ごとに1回のティック割り込みを行うことはばかげており、しばしば完全に実行不可能です。これは、サイクルカウンターなどが作用する場所です。カーネルは、毎秒(または各ティック)でサイクルカウンター値を記憶し、ナノ秒単位で時間を知りたいときにカウンターの現在の値から、最後の秒から経過したナノ秒数(またはティック)。繰り返しになりますが、命令サイクルの頻度が変化する可能性があるため、電力と熱の管理はこれで大混乱に陥ります。そのため、カーネルは(たとえば)高精度イベントタイマー(HPET)などの追加ハードウェアに依存するなどのことを行います。
C言語とPOSIX
C言語の標準ライブラリは、不透明タイプの点で時間を記述しtime_t
、構造型tm
の様々な指定されたフィールドを持つ、など様々なライブラリ関数time()
、mktime()
、およびlocaltime()
。
簡単に言うと、C言語自体time_t
は、それが利用可能な数値データ型の1つであり、時間差を計算する唯一の信頼できる方法がdifftime()
関数であることを保証するだけです。time_t
実際には整数型の1つであり、エポック以降の秒数をカウントするという厳密な保証を提供するのはPOSIX標準です。また、timespec
構造タイプを指定するPOSIX標準でもあります。
このtime()
関数は、システムコールと呼ばれることもあります。実際、今日では多くのシステムの基になるシステムコールではありませんでした。たとえば、FreeBSDでは、基になるシステムコールはclock_gettime()
であり、さまざまな方法で秒または秒+ナノ秒で測定するさまざまな「クロック」を使用できます。アプリケーションソフトウェアがカーネルからUNIX Timeを読み取るのは、このシステムコールです。(一致するclock_settime()
システムコールによりステップ実行adjtime()
でき、システムコールによりスルーできます。)
多くの人々は、POSIX標準が規定するものについて非常に明確で正確な主張をして、POSIX標準を振り回しています。そのような人々は、多くの場合、実際にPOSIX標準を読んでいません。その理論的根拠が示すように、「エポックからの秒数」をカウントするという考え方は、標準が使用するフレーズであり、POSIX秒がSI秒と同じ長さであることも、結果が「必然的に」であることも意図的に指定していませんgmtime()
UTC、その外観にもかかわらず」。POSIX標準は意図的に(たとえば)管理者が行って、うるう秒調整が発生した週にクロックを再設定することにより、うるう秒調整を手動で修正するUNIXシステムを可能にするほど十分に緩い。実際、理論的根拠は、クロックが現在のUTC時間以外の時間に意図的に誤って設定されているシステムに対応するために意図的に十分に緩いことを指摘しています。
UTCおよびTAI
カーネルから取得したUNIX Timeの解釈は、アプリケーションで実行されるライブラリルーチンに依存します。POSIXは、カーネルの時間との「壊れた時間」の間のIDを指定しますstruct tm
。しかし、Daniel J. 「違反よりも名誉を守ること」は、すぐに思い浮かぶフレーズです。
そして確かにそうです。現在、いくつかのシステムは、この解釈をArthur David Olsonによって書かれたライブラリルーチンに基づいています。このルーチンは、悪名高い「Olsonタイムゾーンデータベース」を参照します/usr/share/zoneinfo/
。Olsonシステムには2つのモードがありました。
- カーネルの「エポックからの秒数」は、うるう秒を除き、1970-01-01 00:00:00 UTC以降のUTC秒をカウントすると見なされます。これは、
posix/
Olsonタイムゾーンデータベースファイルのセットを使用します。すべての日には86400カーネル秒があり、1分に61秒はありませんが、SI秒の長さであるとは限りません。また、うるう秒の発生時にカーネルクロックを回転またはステップ移動する必要があります。
- カーネルの「エポックからの秒数」は、1970-01-01 00:00:10 TAI以降のTAI秒をカウントすると見なされます。これは、
right/
Olsonタイムゾーンデータベースファイルのセットを使用します。カーネル秒は1 SI秒長であり、カーネルクロックはthe秒を調整するために旋回またはステップ移動する必要はありませんが、ブレークダウン時間は23:59:60などの値を持つことができ、日は常に86400カーネル秒の長さではありません。
M. Bernsteinは、1970-01-01 00:00:00 TAIからTAI秒を取得するために10を追加しただけdaemontools
なright/
ので、ツールセットを含むいくつかのツールを作成しましたtime_t
。彼はこれをマニュアルページに文書化した。
この要件は、(おそらく無意識のうちに)daemontools-encore
およびなどのツールセットによって継承さrunit
れ、Felix von Leitner'sによって継承されましたlibowfat
。たとえば、Olson 構成でBernsteinmultilog
、Guentermultilog
、またはPapesvlogd
を使用するposix/
と、すべてのTAI64Nタイムスタンプは(これを書いている時点で)1970-01-01 00:00:10以降の実際の TAI秒カウントより26秒遅れます。 TAI。
Laurent Bercotと私は、s6とnoshでこれに対処しましたが、異なるアプローチを採用しました。M. Bercot tai_from_sysclock()
はコンパイル時フラグに依存しています。でTAI64Nルックで取引することを間食ツールTZ
とTZDIR
の環境変数を自動検出posix/
し、right/
それができれば。
興味深いことに、TAI秒としてOlson モードに相当するFreeBSDのドキュメントtime2posix()
とposix2time()
機能。ただし、明らかに有効化されていません。right/
time_t
もう一度…
UNIX時間は、UNIXを実行しているコンピューターで、コンピューターのハードウェアに含まれるオシレーターによって測定されます。SI秒は使用しません。表面的には似ているかもしれませんが、UTCではありません。そして、それはあなたの時計が間違っていることを意図的に許可します。
参考文献