【C言語】現在時刻をマイクロ秒で取得する方法【Windows/UNIX】

この記事では、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は比較的軽量ですが、精度が劣る場合があります。

精度の違いとその影響

精度の違いは、特にリアルタイムシステムや高精度なパフォーマンス測定において重要です。

高精度が求められる場合は、QueryPerformanceCounterclock_gettimeを使用することが推奨されます。

まとめ

C言語で現在時刻をマイクロ秒単位で取得する方法について、WindowsとUNIXの両方の環境での実装方法を解説しました。

WindowsではGetSystemTimeAsFileTimeQueryPerformanceCounterを、UNIXではgettimeofdayclock_gettimeを使用することで、精度の高い時間測定が可能です。

また、クロスプラットフォーム対応のコードを作成することで、異なる環境でも一貫した動作を実現できます。

パフォーマンスと精度のバランスを考慮しながら、適切な方法を選択してください。

目次から探す