Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all bug

名前

       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  を返し、  errnoEINTR  を設定し、 rem が NULL でなければ 残りの時間を rem が指す構造体に格納する。 *rem の
       値を使うと、 nanosleep()  をもう一度呼び出して、指定した時間の停止を  完了させることができ
       る (但し、「注意」の節を参照のこと)。

       ナノ秒刻みの時間間隔を指定するのに timespec 構造体が使用される。この構造体は次のように定義
       されている。

           struct 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(2)     の仕様には、
       CLOCK_REALTIME の不連続な変化は nanosleep()   に影響すべきではない、と書かれているからであ
       る。

              clock_settime(2)  経由で CLOCK_REALTIME クロックの値を設定しても、 nanosleep() 関数
              などの CLOCK_REALTIME  に基づくサービスにより相対的な期間だけ実行を停止するスレッド
              には影響はない。 結果として、クロック値が更新前か後かに関わらず、要求された相対的な
              時間が 経過すると満了することになる。

   以前の動作
       (例えば、時間が重要な意味を持つハードウェアを制御する場合など)  より正確な停止を必要とする
       アプリケーションに対応するために、 nanosleep()  は、マイクロ秒精度のビジーウェイトを利用す
       ることで、 2 ms 以下の停止を行うことができた。  但し、この機能を利用するには、呼び出し元の
       スレッドが SCHED_FIFOSCHED_RR といったリアルタイムポリシーの元でスケジューリングされて
       いる 必要があった。 この特別な拡張はカーネル 2.5.39 で削除された。したがって、 現在の  2.4
       系列のカーネルにはこの機能が存在するが、 2.6系列のカーネルにはない。

バグ

       Linux   2.4   では、   nanosleep()   が  (SIGTSTP  などの)  シグナルにより停止された場合、
       nanosleep()  の呼び出しは SIGCONT  シグナルによるスレッドの再開後に  EINTR  エラーで失敗す
       る。 システムコールがこの後で再スタートされた場合、 スレッドが停止状態にある間に経過した時
       間は 停止期間としてカウント「されない」。

関連項目

       clock_nanosleep(2), restart_syscall(2), sched_setscheduler(2), timer_create(2),  sleep(3),
       usleep(3), time(7)

この文書について

       この  man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト
       の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。