プログラム内から様々な種類のシステムクロックを取得・設定する方法を紹介します。ハードウェアクロックについては、Howto:リアルタイムクロックへの時刻の保存方法を参照してください。
1. さまざまな時間を取得・設定する方法
プログラム内から時間を取得・設定するAPIとして代表的なものに、gettimeofday()/settimeofday()がありますが
これらはすでに非推奨となっているため、現在推奨されているclock_gettime()/clock_settime()を使用します。
以下が現在の時間を取得するサンプルコードです。
#include <stdio.h>
#include <time.h>
int main(int argc, char *argv[])
{
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
printf("tv_sec = %ld, tv_nsec = %ld\n", ts.tv_sec, ts.tv_nsec);
return 0;
}
clock_gettime()の第一引数を変えることでさまざまな時間を取得できます。
以下のような種類があります。
パラメータ | 説明 |
---|---|
CLOCK_REALTIME | 現在のシステム時刻(いわゆる時計)。adjtime()1やNTPによる補正2、および手動での時間の変更の影響を受ける。 |
CLOCK_REALTIME_COARSE | 高速に動作するが精度の低いCLOCK_REALTIME。 |
CLOCK_MONOTONIC | ある時点3からの単調増加な経過時間。手動での時間変更の影響は受けないが、adjtime()やNTPによる段階的な補正の影響は受ける。取得のみで設定することは不可。 |
CLOCK_MONOTONIC_COARSE | 高速に動作するが精度の低いCLOCK_MONOTONIC。 |
CLOCK_MONOTONIC_RAW | adjtime()やNTPによる補正の影響も受けないCLOCK_MONOTONIC。 |
CLOCK_BOOTTIME | システムがサスペンドしている時間も含まれるCLOCK_MONOTONIC。 |
CLOCK_PROCESS_CPUTIME_ID | このプロセスで消費されたCPU時間。 |
CLOCK_THREAD_CPUTIME_ID | スレッド単位での消費されたCPU時間。 |
用途に合わせてパラメータを選択する
以下に用途別のパラメータの例を挙げます。
用途の例 | パラメータ |
---|---|
現在時刻を取得したい | CLOCK_REALTIME |
プログラム内で周期的な処理を行いたい | CLOCK_MONOTONIC4 常に増加することが保証されているので補正の影響で時間がもどったりはしません。 |
プログラムのCPU時間を計測したい | CLOCK_PROCESS_CPUTIME_ID sleep()などで止まっている間は時間は増えません。 |
スレッド単位でのCPU時間を計測したい | CLOCK_THREAD_CPUTIME_ID |
2. 時間の精度
精度はclock_getres()で取得できます。
#include <stdio.h>
#include <time.h>
int main(int argc, char *argv[])
{
struct timespec ts;
clock_getres(CLOCK_REALTIME, &ts);
printf("tv_sec = %ld, tv_nsec = %ld\n", ts.tv_sec, ts.tv_nsec);
return 0;
}
また、以下のコマンドでも確認できます。
[armadillo ~]# cat /proc/timer_list | grep resolution
.resolution: 1 nsecs
.resolution: 1 nsecs
.resolution: 1 nsecs
.resolution: 1 nsecs