nanosleep
Section: System Calls (2)
Updated: 2026-02-08
Index
JM Home Page
roff page
名前
nanosleep - 高精度なスリープ
ライブラリ
標準 C ライブラリ (libc, -lc)
書式
#include <time.h>
int nanosleep(const struct timespec *duration,
struct timespec *_Nullable rem);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
nanosleep():
_POSIX_C_SOURCE >= 199309L
説明
nanosleep() は、少なくとも *duration
で指定された時間が経過するか、呼び出しスレッド内のハンドラの呼び出しをトリガするシグナルまたはプロセスを終了するシグナルが配信されるまで、呼び出しスレッドの実行を一時停止します。
呼び出しがシグナルハンドラにより割り込まれた場合、 nanosleep は -1 を返し、 errno に EINTR を設定し、
rem が NULL でなければ 残りの時間を rem が指す構造体に格納します。 *rem の値を使うと、
nanosleep() をもう一度呼び出して、指定した時間の停止を完了させることができます (但し、「注意」の節を参照のこと)。
ナノ秒刻みの時間間隔を指定するのに timespec 構造体が使用されます。
ナノ秒のフィールドの値は 0 から 999999999 の範囲になければなりません。
sleep(3) や usleep(3) に比べると nanosleep() には以下のような利点があります:
停止期間の指定に関して高い時間分解能が提供されています。シグナルと互いに影響を及ぼすことがないと POSIX.1
で明示的に規定されています。シグナルハンドラによって割り込まれた際に、停止を再開するのが より簡単にできます。
返り値
要求された期間の停止に成功した場合、 nanosleep() は 0 を返します。呼び出しがシグナルハンドラにより割り込まれたり、
エラーが発生した場合は、-1 を返し、 errno にエラー内容を示す値を設定します。
エラー
- EFAULT
-
ユーザー空間からの情報のコピーで問題がありました。
- EINTR
-
そのスレッドに配送されたシグナルにより停止が中断されました (signal(7) 参照)。スレッドが簡単に nanosleep()
を再び呼び出して停止を続けることができるように、残りの停止時間が *rem に格納されます。
- EINVAL
-
tv_nsec フィールドの値が [0 から 999999999] の範囲でないか、 tv_sec の値が負でした。
バージョン
POSIX.1 は、 nanosleep() は CLOCK_REALTIME
に対して時刻を計測するべきだと規定しています。しかしながら、Linux は CLOCK_MONOTONIC
クロックを用いて時刻を計測しています。このことはおそらく問題にならないでしょう。なぜなら、POSIX.1 の clock_settime(2)
の仕様には、 CLOCK_REALTIME の不連続な変化は nanosleep() に影響すべきではない、と書かれているからです。
-
clock_settime(2) を使用して CLOCK_REALTIME クロックの値を設定しても、nanosleep()
関数を含む、このクロックに基づく相対タイムサービスを待機してブロックされているスレッドには影響しません。したがって、これらのタイムサービスは、クロックの新しい値または古い値に関係なく、要求された期間が経過すると満了になります。
標準
POSIX.1-2024.
履歴
POSIX.1-2001.
より正確な停止を必要とするアプリケーションをサポートするために(たとえば、タイムクリティカルなハードウェアを制御するために)、nanosleep()
は、SCHED_FIFO や SCHED_RR
のようなリアルタイムポリシーの下でスケジュールされたスレッドから呼び出されたときに、マイクロ秒精度でビジー待機することによって最大
2ミリ秒の停止を処理します。この特別な拡張は Linux 2.5.39 で削除されたため、Linux 2.6.0 以降のカーネルでは利用できません。
注意
duration が正確に基本クロックの粒度の倍数でない場合
(time(7)参照)、時間間隔は次の倍数に切り上げられます。さらに、スリープが完了した後、CPU
が再び呼び出しスレッドを実行できるようになるまでには、まだ遅延が存在する可能性があります。
シグナルによる割り込み後に繰り返し再開された場合、 nanosleep()
の停止が相対的な期間であることは問題となることがあります。これは、呼び出しの割り込みから再開までの間の時間が原因で
停止が最終的に完了した際に時間にずれが発生するからです。この問題は、絶対時刻が指定できる clock_nanosleep(2)
を使うことで回避できます。
バグ
シグナルをキャッチして nanosleep()
を使用するプログラムが非常に高いレートでシグナルを受信する場合、スケジューリング遅延と、カーネルによるスリープ間隔の計算における丸め誤差、および返された
remain 値は、remain コールの連続的な再起動時に increase 値が着実に nanosleep()
になる可能性があることを意味します。このような問題を回避するには、TIMER_ABSTIME フラグを指定して
clock_nanosleep(2) を使用し、絶対的なデッドラインまでスリープするようにします。
Linux 2.4 では、 nanosleep() が (SIGTSTP などの) シグナルにより停止された場合、
nanosleep() の呼び出しは SIGCONT シグナルによるスレッドの再開後に EINTR
エラーで失敗すします。システムコールがこの後で再スタートされた場合、スレッドが停止状態にある間に経過した時間は
停止期間としてカウントされません。この問題は Linux 2.6.0 とそれ以降のカーネルでは修正されています。
関連項目
clock_nanosleep(2), restart_syscall(2), sched_setscheduler(2),
timer_create(2), sleep(3), timespec(3), usleep(3), time(7)
Index
- 名前
-
- ライブラリ
-
- 書式
-
- 説明
-
- 返り値
-
- エラー
-
- バージョン
-
- 標準
-
- 履歴
-
- 注意
-
- バグ
-
- 関連項目
-
This document was created by
man2html,
using the manual pages.