C 言語で nanosleep 関数を使用する
この記事では、C 言語で nanosleep
関数を利用する方法をいくつか説明します。
関数 nanosleep
を使って C 言語で高分解能タイマを使ってプログラムの実行を中断する
nanosleep
は POSIX に準拠したシステムコールであり、プログラムの実行を一定時間中断するためのものです。他の関数も同様の処理を行う機能を提供しているが、sleep
はそのうちの一つであり、呼び出し処理を中断するのに数秒かかる。sleep
は低解像度の中断を提供すると言われています。これに対して、nanosleep
では、ユーザがナノ秒単位の精度でスリープ期間を指定することができます。
関数 nanosleep
は struct timespec
オブジェクト型の 2つのアドレスを受け取ります。秒数を表す tv_sec
とナノ秒数を表す tv_nsec
です。最初の timespec
構造体は一時停止の期間を指定するために使われます。なお、tv_nsec
の値は 0 から 999999999 の範囲内でなければならないことに注意してください。次の例では、10 回の繰り返しでループを実行し、5 サイクル目に nanosleep
を呼び出してプロセスを中断しています。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };
int main() {
struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};
printf("Started loop..\n");
for (int i = 0; i < 10; ++i) {
printf("Iteration - %d\n", i);
if (i == 4) {
printf("Sleeping ....\n");
nanosleep(&request, &remaining);
}
}
exit(EXIT_SUCCESS);
}
出力:
Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9
C 言語で nanosleep
関数が正常に実行されたかどうかを調べる
nanosleep
は与えられた期間だけプロセスを中断させるべきであるが、システム内にはそれを中断してエラーコードを返し、errno
を EINTR
に設定するよう強制するイベントが存在します。この場合、第 2 引数 timespec
は、関数呼び出しがシグナルによって中断された残りの期間を格納するために使用されます。このオブジェクトはその後再び nanosleep
を呼び出して、今度はスリープを終了させることができます。次の例では、複数のエラーコードをチェックし、対応するメッセージを表示し、必要に応じてコードの実行を処理する方法を示します。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum { SECS_TO_SLEEP = 3, NSEC_TO_SLEEP = 125 };
int main() {
struct timespec remaining, request = {SECS_TO_SLEEP, NSEC_TO_SLEEP};
printf("Started loop..\n");
for (int i = 0; i < 10; ++i) {
printf("Iteration - %d\n", i);
if (i == 4) {
printf("Sleeping ....\n");
errno = 0;
if (nanosleep(&request, &remaining) == -1) {
switch (errno) {
case EINTR:
printf("interrupted by a signal handler\n");
exit(EXIT_FAILURE);
case EINVAL:
printf("tv_nsec - not in range or tv_sec is negative\n");
exit(EXIT_FAILURE);
default:
perror("nanosleep");
exit(EXIT_FAILURE);
}
}
}
}
exit(EXIT_SUCCESS);
}
出力:
Started loop..
Iteration - 0
Iteration - 1
Iteration - 2
Iteration - 3
Iteration - 4
Sleeping ....
Iteration - 5
Iteration - 6
Iteration - 7
Iteration - 8
Iteration - 9