この記事では、C言語を使って現在の時刻をマイクロ秒単位で取得する方法を解説します。
WindowsとUNIXの両方の環境での具体的な方法を紹介し、サンプルコードも提供します。
初心者の方でも理解しやすいように、基本的な前提知識から丁寧に説明しますので、ぜひ参考にしてください。
C言語で現在時刻をマイクロ秒で取得する方法【Windows/UNIX】
前提知識
マイクロ秒とは
マイクロ秒(μs)は、1秒の100万分の1の時間単位です。
非常に短い時間を測定するために使用され、プログラムのパフォーマンス測定やリアルタイムシステムでの時間管理において重要な役割を果たします。
C言語での時間管理の基本
C言語では、標準ライブラリを使用して時間を管理することができます。
time.hヘッダーファイル
には、時間を扱うための関数やデータ型が定義されています。
しかし、標準ライブラリだけではマイクロ秒単位の精度を得ることは難しいため、WindowsやUNIXのAPIを利用する必要があります。
Windows環境での現在時刻の取得
Windows APIの利用
GetSystemTimeAsFileTime関数の概要
GetSystemTimeAsFileTime関数
は、システム時刻をファイル時刻形式で取得するためのWindows APIです。
ファイル時刻は、1601年1月1日からの経過時間を100ナノ秒単位で表現します。
GetSystemTimeAsFileTime関数の使い方
この関数を使用するには、<windows.h>ヘッダーファイル
をインクルードし、FILETIME
構造体を使用します。
取得した時刻をマイクロ秒に変換するためには、100ナノ秒単位をマイクロ秒単位に変換する必要があります。
QueryPerformanceCounter関数の利用
QueryPerformanceCounter関数の概要
QueryPerformanceCounter関数
は、高精度のパフォーマンスカウンタの現在値を取得するためのWindows APIです。
この関数は、非常に高い精度で時間を測定することができます。
QueryPerformanceCounter関数の使い方
この関数を使用するには、<windows.h>ヘッダーファイル
をインクルードし、LARGE_INTEGER
構造体を使用します。
また、カウンタの周波数を取得するためにQueryPerformanceFrequency関数
も使用します。
サンプルコード
GetSystemTimeAsFileTimeを使ったサンプルコード
以下は、GetSystemTimeAsFileTime関数
を使用して現在時刻をマイクロ秒単位で取得するサンプルコードです。
#include <stdio.h>
#include <windows.h>
int main() {
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
// 100ナノ秒単位をマイクロ秒単位に変換
ULARGE_INTEGER uli;
uli.LowPart = ft.dwLowDateTime;
uli.HighPart = ft.dwHighDateTime;
unsigned long long microseconds = uli.QuadPart / 10;
printf("Current time in microseconds: %llu\n", microseconds);
return 0;
}
QueryPerformanceCounterを使ったサンプルコード
以下は、QueryPerformanceCounter関数
を使用して現在時刻をマイクロ秒単位で取得するサンプルコードです。
#include <stdio.h>
#include <windows.h>
int main() {
LARGE_INTEGER frequency, counter;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&counter);
// カウンタの値をマイクロ秒単位に変換
unsigned long long microseconds = (counter.QuadPart * 1000000) / frequency.QuadPart;
printf("Current time in microseconds: %llu\n", microseconds);
return 0;
}
UNIX環境での現在時刻の取得
POSIX標準の利用
gettimeofday関数の概要
gettimeofday関数
は、現在の時刻を秒とマイクロ秒単位で取得するためのPOSIX標準の関数です。
この関数は、<sys/time.h>ヘッダーファイル
に定義されています。
gettimeofday関数の使い方
この関数を使用するには、<sys/time.h>ヘッダーファイル
をインクルードし、struct timeval
構造体を使用します。
tv_sec
メンバーは秒を、tv_usec
メンバーはマイクロ秒を表します。
clock_gettime関数の利用
clock_gettime関数の概要
clock_gettime関数
は、指定されたクロックの現在時刻を取得するためのPOSIX標準の関数です。
この関数は、<time.h>ヘッダーファイル
に定義されています。
clock_gettime関数の使い方
この関数を使用するには、<time.h>ヘッダーファイル
をインクルードし、struct timespec
構造体を使用します。
tv_sec
メンバーは秒を、tv_nsec
メンバーはナノ秒を表します。
サンプルコード
gettimeofdayを使ったサンプルコード
以下は、gettimeofday関数
を使用して現在時刻をマイクロ秒単位で取得するサンプルコードです。
#include <stdio.h>
#include <sys/time.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
unsigned long long microseconds = tv.tv_sec * 1000000 + tv.tv_usec;
printf("Current time in microseconds: %llu\n", microseconds);
return 0;
}
clock_gettimeを使ったサンプルコード
以下は、clock_gettime関数
を使用して現在時刻をマイクロ秒単位で取得するサンプルコードです。
#include <stdio.h>
#include <time.h>
int main() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
unsigned long long microseconds = ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
printf("Current time in microseconds: %llu\n", microseconds);
return 0;
}
クロスプラットフォーム対応
プリプロセッサディレクティブの利用
#ifdefと#endifの使い方
クロスプラットフォーム対応のコードを書くためには、プリプロセッサディレクティブを使用して、コンパイル時に適切なコードを選択することが重要です。
#ifdef
と#endif
を使用して、WindowsとUNIXのコードを分岐させることができます。
クロスプラットフォーム対応のサンプルコード
以下は、WindowsとUNIXの両方で動作するクロスプラットフォーム対応のサンプルコードです。
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
unsigned long long get_current_time_microseconds() {
LARGE_INTEGER frequency, counter;
QueryPerformanceFrequency(&frequency);
QueryPerformanceCounter(&counter);
return (counter.QuadPart * 1000000) / frequency.QuadPart;
}
#else
#include <sys/time.h>
unsigned long long get_current_time_microseconds() {
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec;
}
#endif
int main() {
unsigned long long microseconds = get_current_time_microseconds();
printf("Current time in microseconds: %llu\n", microseconds);
return 0;
}
パフォーマンスと精度の考慮
各方法のパフォーマンス比較
WindowsとUNIXで使用する各方法のパフォーマンスは異なります。
QueryPerformanceCounter
は非常に高い精度を持ちますが、システムによってはオーバーヘッドが大きくなることがあります。
一方、gettimeofday
は比較的軽量ですが、精度が劣る場合があります。
精度の違いとその影響
精度の違いは、特にリアルタイムシステムや高精度なパフォーマンス測定において重要です。
高精度が求められる場合は、QueryPerformanceCounter
やclock_gettime
を使用することが推奨されます。
まとめ
C言語で現在時刻をマイクロ秒単位で取得する方法について、WindowsとUNIXの両方の環境での実装方法を解説しました。
WindowsではGetSystemTimeAsFileTime
やQueryPerformanceCounter
を、UNIXではgettimeofday
やclock_gettime
を使用することで、精度の高い時間測定が可能です。
また、クロスプラットフォーム対応のコードを作成することで、異なる環境でも一貫した動作を実現できます。
パフォーマンスと精度のバランスを考慮しながら、適切な方法を選択してください。