[C言語] 現在時刻をミリ秒単位で取得する方法

C言語で現在時刻をミリ秒単位で取得するには、time.hライブラリのclock_gettime関数やgettimeofday関数を使用します。

これらの関数は、システムクロックからの時間をナノ秒またはマイクロ秒単位で取得し、それをミリ秒に変換することで実現します。

特にclock_gettimeは高精度なタイムスタンプを提供し、struct timespecを使用して秒とナノ秒を取得します。

一方、gettimeofdaystruct timevalを使用し、秒とマイクロ秒を取得します。

この記事でわかること
  • clock()、gettimeofday()、QueryPerformanceCounter()、clock_gettime()を用いた時刻取得方法
  • 各関数の精度とプラットフォームごとの違い
  • ミリ秒単位の時刻取得を活用した応用例
  • ミリ秒単位の時刻取得が必要な理由とその重要性

目次から探す

ミリ秒単位の時刻取得

C言語で現在時刻をミリ秒単位で取得する方法は、プラットフォームや使用するライブラリによって異なります。

以下では、代表的な方法をいくつか紹介します。

clock()関数の利用

clock()関数は、プログラムの実行時間を取得するために使用されますが、ミリ秒単位の精度を持たないことが多いです。

以下は、clock()関数を使用したサンプルコードです。

#include <stdio.h>
#include <time.h>
int main() {
    // プログラム開始時のクロックを取得
    clock_t start = clock();
    // 何らかの処理
    for (volatile long i = 0; i < 1000000; i++);
    // プログラム終了時のクロックを取得
    clock_t end = clock();
    // 経過時間をミリ秒単位で計算
    double elapsed_time = (double)(end - start) / CLOCKS_PER_SEC * 1000;
    printf("経過時間: %.2f ミリ秒\n", elapsed_time);
    return 0;
}
経過時間: 15.00 ミリ秒

このコードは、プログラムの実行時間をミリ秒単位で計測しますが、clock()関数の精度は環境によって異なるため、注意が必要です。

gettimeofday()関数の利用

gettimeofday()関数は、UNIX系システムで使用可能な関数で、マイクロ秒単位の時刻を取得できます。

以下は、gettimeofday()を使用したサンプルコードです。

#include <stdio.h>
#include <sys/time.h>
int main() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    // 秒とマイクロ秒をミリ秒に変換
    long milliseconds = tv.tv_sec * 1000 + tv.tv_usec / 1000;
    printf("現在時刻: %ld ミリ秒\n", milliseconds);
    return 0;
}
現在時刻: 1634567890123 ミリ秒

このコードは、現在時刻をミリ秒単位で取得します。

gettimeofday()は高精度な時刻取得が可能です。

Windows環境でのQueryPerformanceCounter()の利用

Windows環境では、QueryPerformanceCounter()を使用して高精度な時刻を取得できます。

以下は、QueryPerformanceCounter()を使用したサンプルコードです。

#include <stdio.h>
#include <windows.h>
int main() {
    LARGE_INTEGER frequency, start, end;
    QueryPerformanceFrequency(&frequency);
    QueryPerformanceCounter(&start);
    // 何らかの処理
    for (volatile long i = 0; i < 1000000; i++);
    QueryPerformanceCounter(&end);
    // 経過時間をミリ秒単位で計算
    double elapsed_time = (double)(end.QuadPart - start.QuadPart) * 1000.0 / frequency.QuadPart;
    printf("経過時間: %.2f ミリ秒\n", elapsed_time);
    return 0;
}
経過時間: 10.00 ミリ秒

このコードは、Windows環境で高精度な経過時間をミリ秒単位で計測します。

POSIX環境でのclock_gettime()の利用

POSIX環境では、clock_gettime()を使用してナノ秒単位の時刻を取得できます。

以下は、clock_gettime()を使用したサンプルコードです。

#include <stdio.h>
#include <time.h>
int main() {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    // 秒とナノ秒をミリ秒に変換
    long milliseconds = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
    printf("現在時刻: %ld ミリ秒\n", milliseconds);
    return 0;
}
現在時刻: 1634567890123 ミリ秒

このコードは、POSIX環境で現在時刻をミリ秒単位で取得します。

clock_gettime()は非常に高精度な時刻取得が可能です。

応用例

ミリ秒単位で時刻を取得する技術は、さまざまな応用が可能です。

以下にいくつかの具体的な応用例を紹介します。

時間計測を用いたパフォーマンス測定

プログラムのパフォーマンスを測定する際に、処理時間をミリ秒単位で計測することは非常に有用です。

特に、アルゴリズムの最適化や、異なる実装の比較を行う際に役立ちます。

#include <stdio.h>
#include <time.h>
void someFunction() {
    // 何らかの処理
    for (volatile long i = 0; i < 1000000; i++);
}
int main() {
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    someFunction();
    clock_gettime(CLOCK_MONOTONIC, &end);
    // 経過時間をミリ秒単位で計算
    long elapsed_time = (end.tv_sec - start.tv_sec) * 1000 + (end.tv_nsec - start.tv_nsec) / 1000000;
    printf("関数の実行時間: %ld ミリ秒\n", elapsed_time);
    return 0;
}

このコードは、someFunction()の実行時間をミリ秒単位で計測します。

パフォーマンスのボトルネックを特定するのに役立ちます。

ミリ秒単位のタイマーの実装

ミリ秒単位のタイマーは、一定時間後に特定の処理を実行するために使用されます。

以下は、簡単なタイマーの実装例です。

#include <stdio.h>
#include <time.h>
#include <unistd.h>
void timerCallback() {
    printf("タイマーが終了しました!\n");
}
int main() {
    struct timespec start, current;
    long duration = 5000; // タイマーの時間(ミリ秒)
    clock_gettime(CLOCK_MONOTONIC, &start);
    while (1) {
        clock_gettime(CLOCK_MONOTONIC, ¤t);
        long elapsed_time = (current.tv_sec - start.tv_sec) * 1000 + (current.tv_nsec - start.tv_nsec) / 1000000;
        if (elapsed_time >= duration) {
            timerCallback();
            break;
        }
        usleep(1000); // 1ミリ秒待機
    }
    return 0;
}

このコードは、5秒後にtimerCallback()を呼び出すタイマーを実装しています。

usleep()を使用してCPU負荷を軽減しています。

リアルタイムシステムでの利用

リアルタイムシステムでは、正確な時間管理が求められます。

ミリ秒単位の時刻取得は、タスクのスケジューリングやデッドラインの管理に不可欠です。

リアルタイムシステムでは、clock_gettime()QueryPerformanceCounter()のような高精度な時刻取得関数を使用して、タスクの実行タイミングを厳密に管理します。

これにより、システムの応答性を向上させ、タイムクリティカルな処理を確実に行うことができます。

リアルタイムシステムでの具体的な実装は、システムの要件や使用するOSによって異なりますが、ミリ秒単位の精度を持つ時刻取得は、リアルタイム性を確保するための重要な要素です。

よくある質問

ミリ秒単位の精度はどの程度ですか?

ミリ秒単位の精度は、使用する関数やプラットフォームによって異なります。

例えば、clock()関数は一般的に低精度で、環境によっては数十ミリ秒の誤差が生じることがあります。

一方、gettimeofday()clock_gettime()は、マイクロ秒やナノ秒単位の精度を持ち、より高精度な時刻取得が可能です。

WindowsのQueryPerformanceCounter()も高精度で、ナノ秒単位の精度を提供します。

WindowsとLinuxでの実装の違いはありますか?

WindowsとLinuxでは、時刻取得のためのAPIが異なります。

WindowsではQueryPerformanceCounter()GetSystemTimeAsFileTime()が一般的に使用され、高精度な時刻取得が可能です。

Linuxや他のUNIX系システムでは、gettimeofday()clock_gettime()が使用されます。

これらの関数は、プラットフォームに依存した実装となるため、クロスプラットフォームでの開発時には注意が必要です。

ミリ秒単位の時刻取得が必要な理由は何ですか?

ミリ秒単位の時刻取得は、以下のような理由で必要とされます:

  • パフォーマンス測定:プログラムやアルゴリズムの実行時間を正確に測定するため。
  • リアルタイムアプリケーション:正確なタイミングが求められるリアルタイムシステムやゲーム開発において、イベントのタイミングを管理するため。
  • データ同期:分散システムやネットワークアプリケーションで、データの同期やタイムスタンプの管理を行うため。

まとめ

ミリ秒単位での時刻取得は、C言語プログラミングにおいて重要な技術であり、さまざまな応用が可能です。

この記事では、clock()gettimeofday()QueryPerformanceCounter()clock_gettime()などの関数を用いた時刻取得方法を紹介しました。

これらの技術を活用することで、プログラムのパフォーマンス測定やリアルタイムシステムの開発に役立てることができます。

ぜひ、これらの方法を試して、あなたのプロジェクトに応用してみてください。

  • URLをコピーしました!
目次から探す