NANOSLEEP
Section: Linux Programmer's Manual (2)
Updated: 2009-01-19
Index
JM Home Page
roff page
名前
nanosleep - 高精度なスリープ
書式
#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);
glibc 向けの機能検査マクロの要件
(feature_test_macros(7)
参照):
nanosleep():
_POSIX_C_SOURCE >= 199309L
説明
nanosleep()
は、少なくとも
*req
で指定された時間の間、プログラムの実行を遅延させる。
nanosleep()
は、呼び出したスレッドの実行を、
少なくとも
*req
で指定された時間の間、もしくは呼び出したスレッドでハンドラの起動の
きっかけとなるシグナル、またはプロセスを終了させるシグナルの配送が
行われるまで一時停止する。
呼び出しがシグナルハンドラにより割り込まれた場合、
nanosleep
は -1 を返し、
errno
に
EINTR
を設定し、
rem
が NULL でなければ
残りの時間を
rem
が指す構造体に格納する。
*rem
の値を使うと、
nanosleep()
をもう一度呼び出して、指定した時間の停止を
完了させることができる (但し、「注意」の節を参照のこと)。
ナノ秒刻みの時間間隔を指定するのに
timespec
構造体が使用される。この構造体は次のように定義されている。
time_t tv_sec; /* 秒 */
long tv_nsec; /* ナノ秒 */
};
ナノ秒のフィールドの値は 0 から 999999999 の範囲になければならない。
sleep(3)
や
usleep(3)
に比べると
nanosleep()
には以下のような利点がある:
停止期間の指定に関して高い時間分解能が提供されている。
シグナルと互いに影響を及ぼすことがないと
POSIX.1 で明示的に規定されている。
シグナルハンドラによって割り込まれた際に、停止を再開するのが
より簡単にできる。
返り値
要求された期間の停止に成功した場合、
nanosleep()
は 0 を返す。呼び出しがシグナルハンドラにより割り込まれたり、
エラーが発生した場合は、-1 を返し、
errno
にエラー内容を示す値を設定する。
エラー
- EFAULT
-
ユーザ空間からの情報のコピーで問題があった。
- EINTR
-
そのスレッドに配送されたシグナルにより停止が中断された。
スレッドが簡単に
nanosleep()
を再び呼び出して停止を続けることができるように、
残りの停止時間が *rem に格納される。
- EINVAL
-
tv_nsec
フィールドの値が 0 から 999999999 までの範囲になかったか、
tv_sec
が負であった。
準拠
POSIX.1-2001.
注意
req
で指定された期間が、内部で使用されるクロックの粒度の倍数になっていない
場合、期間は一番近い倍数に切り上げられる。
また、停止が完了した後、CPU が呼び出し元のスレッドを再び実行できるように
なるまでには遅延が入る。
シグナルによる割り込み後に繰り返し再開された場合、
nanosleep()
の停止が相対的な期間であることは問題となることがある。
これは、呼び出しの割り込みから再開までの間の時間が原因で
停止が最終的に完了した際に時間にずれが発生するからである。
この問題は、絶対時刻が指定できる
clock_nanosleep(2)
を使うことで回避できる。
POSIX.1 は、
nanosleep()
は
CLOCK_REALTIME
に対して時刻を計測するべきだと規定している。
しかしながら、Linux は
CLOCK_MONOTONIC
クロックを用いて時刻を計測している。
このことはおそらく問題にならないだろう。
なぜなら、POSIX.1 の
clock_settime()
の仕様には、
CLOCK_REALTIME
の不連続な変化は
nanosleep()
に影響すべきではない、と書かれているからである。
-
clock_settime()
経由で
CLOCK_REALTIME
クロックの値を設定しても、
nanosleep()
関数などの
CLOCK_REALTIME
に基づくサービスにより相対的な期間だけ実行を停止するスレッドには影響はない。
結果として、クロック値が更新前か後かに関わらず、要求された相対的な時間が
経過すると満了することになる。
以前の動作
(例えば、時間が重要な意味を持つハードウェアを制御する場合など)
より正確な停止を必要とするアプリケーションに対応するために、
nanosleep()
は、マイクロ秒精度のビジー・ウェイトを利用することで、
2 ms 以下の停止を行うことができた。
但し、この機能を利用するには、呼び出し元のスレッドが
SCHED_FIFO
や
SCHED_RR
といったリアルタイム・ポリシーの元でスケジューリングされている
必要があった。
この特別な拡張はカーネル 2.5.39 で削除された。したがって、
現在の 2.4 系列のカーネルにはこの機能が存在するが、
2.6系列のカーネルにはない。
バグ
Linux 2.4 では、
nanosleep()
が
(SIGTSTP
などの) シグナルにより停止された場合、
nanosleep()
の呼び出しは
SIGCONT
シグナルによるスレッドの再開後に
EINTR
エラーで失敗する。
システムコールがこの後で再スタートされた場合、
スレッドが停止状態にある間に経過した時間は
停止期間としてカウント「されない」。
関連項目
clock_nanosleep(2),
sched_setscheduler(2),
sleep(3),
timer_create(2),
usleep(3),
time(7)
Index
- 名前
-
- 書式
-
- 説明
-
- 返り値
-
- エラー
-
- 準拠
-
- 注意
-
- 以前の動作
-
- バグ
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.
Time: 03:26:49 GMT, April 25, 2010