回答:
CLOCK_REALTIME
現在のウォールクロックの時刻に関するマシンの最良の推測を表します。以下のようイグナシオとMarkRは言う、この手段CLOCK_REALTIME
システム時刻クロックとして前後にジャンプすることができますは、NTPによる含め、変更されました。
CLOCK_MONOTONIC
過去の任意の固定点からの絶対経過時間を表します。システムの時刻時計の変更による影響は受けません。
再起動を介さずに1台のマシンで観測された2つのイベント間の経過時間を計算する場合CLOCK_MONOTONIC
は、これが最適なオプションです。
Linuxでは、CLOCK_MONOTONIC
POSIXの定義により、サスペンドに費やされた時間を測定しないことに注意してください。CLOCK_BOOTTIME
サスペンド中に実行を継続する単調クロックには、Linux固有を使用できます。
CLOCK_MONOTONIC
というシナリオで最良の選択でありますか?例:パトリオットミサイルシステム
Robert Loveの著書 『LINUX System Programming 2nd Edition』は、第11章363ページの冒頭で具体的に質問に対応しています。
単調な時間ソースの重要な側面は現在の値ではありませんが、時間ソースが厳密に線形に増加していることの保証であり、したがって、2つのサンプリング間の時間差を計算するのに役立ちます
そうは言っても、プロセスがOSの同じインスタンスで実行されていると彼は想定しているので、ドリフトを推定できるように定期的なキャリブレーションを実行することをお勧めします。
CLOCK_REALTIME
NTPの影響を受け、前後に移動できます。CLOCK_MONOTONIC
そうではなく、ティックごとに1ティックずつ進みます。
System.nanoTime()
使用を考え、1000ns以下の時間をCLOCK_MONOTONIC
測定できると思います。たぶんあなたは時々ミリ秒に制限されているシステム時間について考えていますか?
加えて、イグナシオの答えは、CLOCK_REALTIME
時折後方飛躍に前進上がる、とすることができます。CLOCK_MONOTONIC
どちらも行いません。前進し続けるだけです(ただし、再起動時にリセットされる可能性があります)。
堅牢なアプリは、CLOCK_REALTIME
ときどき前方への跳躍を許容できる必要があります(そして、たぶん非常にまれに後方に跳躍する可能性がありますが、これはエッジケースに近いものです)。
ラップトップをサスペンドしたときに何が起こるか想像してみてください- CLOCK_REALTIME
再開後にジャンプしますが、ジャンプCLOCK_MONOTONIC
しません。VMで試してください。
CLOCK_PROCESS_CPUTIME_ID
です。クイックテスト:$ perl -w -MTime::HiRes=clock_gettime,CLOCK_MONOTONIC -E 'say clock_gettime(CLOCK_MONOTONIC)'
-> 706724.117565279。その数はLinuxのシステム稼働時間と一致しますが、標準では任意としています。
CLOCK_MONOTONIC
が、サスペンド/レジュームで停止するLinuxの動作がPOSIXに準拠しているとは思いません。それは過去の定点からの時間であるはずですが、サスペンド/レジュームでクロックを停止すると壊れます。
POSIX 7の引用
POSIX 7は、http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.htmlで両方を指定しています。
CLOCK_REALTIME
:
このクロックは、システムのリアルタイムを測定するクロックを表します。このクロックの場合、clock_gettime()によって返され、clock_settime()によって指定された値は、エポック以降の時間(秒およびナノ秒)を表します。
CLOCK_MONOTONIC
(オプション機能):
このクロックの場合、clock_gettime()によって返される値は、過去の不特定の時点からの時間(秒およびナノ秒単位)を表します(たとえば、システムの起動時間やエポック)。このポイントは、システムの起動後は変わりません。CLOCK_MONOTONICクロックの値は、clock_settime()を介して設定できません。
clock_settime()
重要なヒントを提供します:POSIXシステムはCLOCK_REALITME
それと共に任意に変更できるので、継続的にも順方向にも流れないことに依存しないでください。NTPはを使用して実装clock_settime()
でき、影響を与えるだけCLOCK_REALITME
です。
Linuxカーネルの実装はのためのエポックとして起動時間がかかるようだCLOCK_MONOTONIC
:CLOCK_MONOTONICのための出発点
これをコメントとして追加する評価はありません。したがって、それは補完的な答えになります。
呼び出す頻度にもよりますが、VDSOのLinuxから提供されるのは「クロック」の一部clock_gettime()
のみであることを覚えておく必要があります(つまり、1つのオーバーヘッドをすべて備えたシステムコールは必要ありません。これはLinuxが追加されたときにのみ悪化します。 Spectreのような攻撃から保護するための防御)。
一方でclock_gettime(CLOCK_MONOTONIC,...)
、clock_gettime(CLOCK_REALTIME,...)
とは、gettimeofday()
常に(VDSOによって加速)非常に高速であることを行っている、これはありません、例えばCLOCK_MONOTONIC_RAWまたは他のPOSIXクロックのいずれかに当てはまります。
これは、カーネルのバージョンとアーキテクチャによって変わる可能性があります。
ほとんどのプログラムはこれに注意を払う必要はありませんが、VDSOによって加速されたクロックにレイテンシのスパイクが発生する可能性があります。カーネルがクロックカウンターで共有メモリ領域を更新しているときに、クロックヒットが発生すると、待機する必要があります。終了するカーネル。
これが「証拠」です(ボットをkernel.orgから遠ざけるためのGitHub):https : //github.com/torvalds/linux/commit/2aae950b21e4bc789d1fc6668faf67e8748300b7