Provided by: manpages-ja-dev_0.5.0.0.20131015+dfsg-2_all bug

名前

       sched_setscheduler, sched_getscheduler - スケジューリング・ポリシーとパラメータを設定/取得
       する

書式

       #include <sched.h>

       int sched_setscheduler(pid_t pid, int policy,
                              const struct sched_param *param);

       int sched_getscheduler(pid_t pid);

       struct sched_param {
           ...
           int sched_priority;
           ...
       };

説明

       sched_setscheduler()  は pid で指定された ID  を持つスレッドのスケジューリング・ポリシーや
       それに関連するパラメータを設定する。pid  が  0 の場合は 呼び出したスレッドのスケジューリン
       グ・ポリシーとパラメータが設定される。 引き数 param の解釈は選択されたポリシーによる。  現
       在のところ、Linux では 以下に示す「通常」(リアルタイムでない) スケジューリング・ポリシーが
       サポートされている。

       SCHED_OTHER   標準の、ラウンドロビンによる時分割型のスケジューリング・ポリシー。

       SCHED_BATCH   「バッチ」形式でのプロセスの実行用。

       SCHED_IDLE    「非常に」低い優先度で動作するバックグラウンド・ジョブ用。

       どの実行可能スレッドを選択するかについて、より正確な制御を必要とする  時間の制約が厳しい特
       別なアプリケーション用として、 以下の「リアルタイム」ポリシーもサポートされている。

       SCHED_FIFO    ファーストイン、ファーストアウト型のポリシー。

       SCHED_RR      ラウンドロビン型のポリシー。

       これらのポリシーのそれぞれの動作については以下で説明する。

       sched_getscheduler()  は pid で識別されるスレッドに現在適用されている スケジューリング・ポ
       リシーを尋ねる。pid が 0 ならば、呼び出した スレッド自身のスケジューリング・ポリシーが返さ
       れる。

   スケジューリング・ポリシー (scheduling policy)
       スケジューラ  (scheduler) とはカーネルの構成要素で、 次に CPU で実行される実行可能なスレッ
       ドを決定するものである。  各々のスレッドには、スケジューリング・ポリシーと  「静的」なスケ
       ジューリング優先度 sched_priority が対応付けられ、 これらの設定は sched_setscheduler()  で
       変更できる。 スケジューラは、システム上の全スレッドのスケジューリング・ポリシーと 静的優先
       度に関する知識に基づいて決定を行う。

       通常のスケジューリング・ポリシー (SCHED_OTHER, SCHED_IDLE, SCHED_BATCH) の下でスケジューリ
       ングされるスレッドでは、       sched_priority       はスケジューリングの決定に使用されない
       (sched_priority には 0 を指定しなければならない)。

       リアルタイム・スケジューリング・ポリシー  (SCHED_FIFO, SCHED_RR)  の下でスケジューリングさ
       れるスレッドは、 sched_priority の値は 1 (最低) から 99 (最高) の範囲となる  (数字から分か
       るように、リアルタイム・スレッドは常に通常のスレッドよりも  高い優先度を持つ)。 ここで注意
       すべきなのは、POSIX.1-2001  が要求しているのは、  リアルタイム・ポリシーの実装において最低
       32 種類の異なる優先度レベルが サポートされることだけであり、いくつかのシステムではこの最低
       限の数の   優先度しか提供されていない、ということである。   移植性が必要なプログラムでは、
       sched_get_priority_min(2)  と sched_get_priority_max(2) を使って、あるポリシーがサポートす
       る優先度の範囲を調べるべきである。

       概念としては、 スケジューラはその sched_priority の値それぞれに対して 実行可能なスレッドの
       リストを管理している。 どのスレッドを次に実行するかを決定するために、 スケジューラは静的優
       先度の最も高い空でないリストを探して、 そのリストの先頭のスレッドを選択する。

       各スレッドのスケジューリング・ポリシーは、  そのスレッドが同じ静的優先度を持つスレッドのリ
       ストの中のどこに挿入され、 このリストの中をどのように移動するかを決定する。

       全てのスケジューリングはプリエンプティブ (preemptive) である: より高い優先度のスレッドが実
       行可能になると、現在実行中のスレッドは実行権を 取り上げられ  (preempted)、そのスレッドの静
       的優先度レベルの待ちリストに  戻される。スケジューリング・ポリシーは同じ静的優先度を持つ実
       行可能な スレッドのリストの中で順番のみを決定する。

   SCHED_FIFO: ファーストイン・ファーストアウト・スケジューリング
       SCHED_FIFO は 0 より大きな静的優先度でのみ使用できる。このポリシーでは、 SCHED_FIFO スレッ
       ドが実行可能になった場合、 そのポリシーが SCHED_OTHERSCHED_BATCHSCHED_IDLE の 現在実
       行中のスレッドは直ちに実行権を取り上げられる。 SCHED_FIFO は時分割のない単純なスケジューリ
       ング・アルゴリズムである。 SCHED_FIFO ポリシーでスケジューリングされているスレッドには以下
       の ルールが適用される:

       *  より高い優先度の他のスレッドによって取って代わられた SCHED_FIFO  スレッドはその優先度の
          リストの先頭に留まり続け、  より高い優先度のスレッド全てが停止 (block) した場合に実行を
          再開する。

       *  SCHED_FIFO スレッドが実行可能になった時、その優先度のリストの最後 に挿入される。

       *  sched_setscheduler()  や sched_setparam(2)   は  pid  で指定された  SCHED_FIFO  (または
          SCHED_RR)  スレッドが 実行可能な場合、リストの最初に置く。 結果として、もし優先度が同じ
          だった場合、 現在実行中のスレッドに先んじるかもしれない。 (POSIX.1-2001  ではスレッドは
          リストの最後に行くべきと規定されている。)

       *  sched_yield(2)  を呼び出したスレッドはリストの最後に置かれる。

       その他のイベントによって SCHED_FIFO ポリシーでスケジューリングされるスレッドが同じ優先度の
       実行可能なスレッドの待ちリストの中を移動することはない。

       SCHED_FIFO スレッドは I/O 要求によって停止するか、  より高い優先度のスレッドによって置きか
       えられるか、 sched_yield(2)  を呼び出すまで実行を続ける。

   SCHED_RR: ラウンドロビン (round-robin)・スケジューリング
       SCHED_RRSCHED_FIFO  の単純な拡張である。  上述された  SCHED_FIFO  に関する記述は全て
       SCHED_RR に 適用できる。異なるのは それぞれのスレッドは最大時間単位までしか実行できない と
       いうことである。 SCHED_RR スレッドが時間単位と同じかそれより 長い時間実行されると、 その優
       先度のリストの最後に置かれる。 より高い優先度のスレッドによって 置きかえられ、その後実行を
       再開した  SCHED_RR  スレッドは、そのラウンド  ロビン時間単位を完全に使い切る  まで実行され
       る。その時間単位の長さは sched_rr_get_interval(2) を使って取得できる。

   SCHED_OTHER: Linux のデフォルトの時分割スケジューリング
       SCHED_OTHER は静的優先度 0 でのみ使用できる。 SCHED_OTHER は Linux  標準の時分割スケジュー
       ラで、 特別なリアルタイム機構を必要としていない全てのスレッドで使用される。 実行するスレッ
       ドは、静的優先度 0 のリストから、このリストの中だけで 決定される「動的な」優先度  (dynamic
       priority)  に基いて決定される。 動的な優先度は (nice(2)  や setpriority(2)  により設定され
       る) nice 値に基づいて決定されるもので、 単位時間毎に、スレッドが実行可能だが、スケジューラ
       により実行が拒否された  場合にインクリメントされる。 これにより、全ての SCHED_OTHER スレッ
       ドでの公平性が保証される。

   SCHED_BATCH: バッチプロセスのスケジューリング
       (Linux 2.6.16 以降)  SCHED_BATCH は静的優先度 0 でのみ使用できる。 このポリシーは (nice 値
       に基づく)       動的な優先度にしたがってスレッドの      スケジューリングが行われるという点
       で、SCHED_OTHER に似ている。 異なるのは、このポリシーでは、スレッドが常に CPU に負荷のかか
       る  (CPU-intensive)  処理を行うと、スケジューラが仮定する点である。 スケジューラはスレッド
       を呼び起こす毎にそのスレッドにスケジューリング上の  ペナルティを少し課し、その結果、このス
       レッドはスケジューリングの決定で 若干冷遇されるようになる。

       このポリシーは、非対話的な処理だがその nice 値を下げたくない処理や、 (処理のタスク間で) 余
       計なタスクの置き換えの原因とある対話的な処理なしで 確定的な (deterministic) スケジューリン
       グ・ポリシーを適用したい処理に 対して有効である。

   SCHED_IDLE: 非常に優先度の低いジョブのスケジューリング
       (Linux 2.6.23 以降)  SCHED_IDLE は静的優先度 0 でのみ使用できる。 このポリシーではプロセス
       の nice 値はスケジューリングに影響を与えない。

       非常に低い優先度でのジョブの実行を目的としたものである     (非常に低い優先度とは、ポリシー
       SCHED_OTHERSCHED_BATCH での nice 値 +19 よりさらに低い優先度である)。

   子プロセスでのスケジューリング・ポリシーのリセット
       Linux  2.6.32 以降では、 sched_setscheduler() を呼び出す際に policySCHED_RESET_ON_FORK
       フラグを OR で指定できる。このフラグが指定されると、 fork(2)  で作成された子プロセスは特権
       が必要なスケジューリング・ポリシーを継承しない。この機能はメディア再生を行うアプリケーショ
       ンを想定して作られ、この機能を使うことで、アプリケーションが複数の子プロセスを作成すること
       で RLIMIT_RTTIME リソース上限 (getrlimit(2) 参照) を回避するのを防ぐことができる。

       より正確には、  SCHED_RESET_ON_FORK フラグが指定された場合、それ以降に作成される子プロセス
       に以下のルールが適用される。

       *  呼び出したスレッドのスケジューリング・ポリシーが SCHED_FIFOSCHED_RR  の場合、子プロ
          セスのポリシーは SCHED_OTHER にリセットされる。

       *  子プロセスが負の nice 値を持っている場合、子プロセスの nice 値は 0 にリセットされる。

       一度  SCHED_RESET_ON_FORK フラグが有効にされた後は、このフラグをリセットできるのは、スレッ
       ドが CAP_SYS_NICE ケーパビリティを持つ場合だけである。このフラグは fork(2)  で作成された子
       プロセスでは無効になる。

       SCHED_RESET_ON_FORK フラグは、 sched_getscheduler() が返すポリシー値で参照できる。

   特権とリソース制限
       2.6.12 より前のバージョンの Linux カーネルでは、 特権スレッド (CAP_SYS_NICE ケーパビリティ
       を持つスレッド) だけが 0 以外の静的優先度を設定する  (すなわち、リアルタイム・スケジューリ
       ング・ポリシーを設定する) ことができる。 非特権スレッドができる変更は SCHED_OTHER ポリシー
       を設定することだけであり、さらにこの変更を行えるのは sched_setscheduler() の呼び出し元の実
       効ユーザ  ID  がポリシーの変更対象スレッド (pid で指定されたスレッド) の実ユーザ ID か実効
       ユーザ ID と 一致する場合だけである。

       Linux 2.6.12 以降では、リソース制限 RLIMIT_RTPRIO が定義されており、  スケジューリング・ポ
       リシーが  SCHED_RRSCHED_FIFO の場合の、非特権スレッドの静的優先度の上限を定めている。
       スケジューリング・ポリシーと優先度を変更する際のルールは以下の通りである。

       *  非特権スレッドに 0 以外の RLIMIT_RTPRIO ソフト・リミットが設定されている場合、 非特権ス
          レッドはそのスレッドのスケジューリング・ポリシーと優先度を 変更できるが、優先度を現在の
          自身の優先度と RLIMIT_RTPRIO ソフト・リミットの大きい方よりも高い値に設定できないという
          制限が課される。

       *  RLIMIT_RTPRIO  ソフト・リミットが  0  の場合、優先度を下げるか、 リアルタイムでないポリ
          シーへ切り替えるかの変更だけが許可される。

       *  ある非特権スレッドが別のスレッドに対してこれらの変更を行う際にも、 同じルールが適用され
          る。変更を行えるのは、変更を行おうとするスレッド の実効ユーザ ID が変更対象のスレッドの
          実ユーザ ID か実効ユーザ ID と 一致している場合に限られる。

       *  SCHED_IDLE の場合には特別なルールが適用される。 2.6.39 より前の Linux  カーネルでは、こ
          のポリシーで動作する非特権スレッドは、 RLIMIT_RTPRIO リソース上限の値に関わらず、自分の
          ポリシーを変更することができない。  2.6.39  以降の  Linux  カーネルでは、非特権スレッド
          は、自分の  nice 値が RLIMIT_NICE リソース上限 (getrlimit(2) 参照) で許可された範囲であ
          る限りは、自分のスケジューリング・ポリシーを SCHED_BATCHSCHED_NORMAL ポリシーに切り
          替えることができる。

       特権スレッド (CAP_SYS_NICE ケーパビリティを持つスレッド) の場合、 RLIMIT_RTPRIO の制限は無
       視される; 古いカーネルと同じように、スケジューリング・ポリシーと優先度に対し  任意の変更を
       行うことができる。 RLIMIT_RTPRIO に関するもっと詳しい情報は getrlimit(2)  を参照のこと。

   応答時間 (response time)
       I/O  待ちで停止したより高い優先度のスレッドは再びスケジューリングされる 前にいくらかの応答
       時間がかかる。デバイス・ドライバーを書く場合には "slow interrupt" 割り込みハンドラーを使用
       することで この応答時間を劇的に減少させることができる。

   その他
       子プロセスは fork(2)  の際に親プロセスのスケジューリング・ポリシーとパラメータを継承する。
       execve(2) の前後で、スケジューリング・ポリシーとパラメータは保持される。

       リアルタイム・プロセスは大抵、ページングの待ち時間を避けるために mlock(2)  や  mlockall(2)
       を使ってメモリ・ロックをしなければならない。

       SCHED_FIFOSCHED_RR でスケジューリングされる スレッドが停止せずに無限ループに陥ると、
       他の全てのより低い優先度のスレッドを永久に停止 (block) させてしまうので、 ソフトウェア開発
       者はコンソールのシェルの静的優先度をテストする  アプリケーションよりも常に高く保つべきであ
       る。 これによって期待通りに停止したり終了したりしないリアルタイム・ アプリケーションを緊急
       終了させることが可能になる。  getrlimit(2)   のリソース制限 RLIMIT_RTTIME の説明も参照のこ
       と。

       POSIX システムでは  <unistd.h>_POSIX_PRIORITY_SCHEDULING  が定義されている場合にのみ
       sched_setscheduler()  と sched_getscheduler()  が使用できる。

返り値

       成功した場合、  sched_setscheduler()  は 0 を返す。 成功した場合、 sched_getscheduler() は
       現在のそのスレッドのポリシー (非負の整数) を返す。 エラーの場合、-1 が返され、 errno  が適
       切に設定される。

エラー

       EINVAL スケジューリング・ポリシー policy が間違っている。 または param が NULL である。 ま
              たは param がそのポリシーでは意味をなさない。

       EPERM  呼び出したスレッドが適切な特権を持っていない。

       ESRCH  ID が pid のスレッドが見つからなかった。

準拠

       POSIX.1-2001 (但し、下記のバグの節も参照)。 SCHED_BATCHSCHED_IDLE ポリシーは Linux  固
       有である。

注意

       POSIX.1  は、非特権スレッドが sched_setscheduler()  を呼び出すために必要な権限の詳細を規定
       しておらず、 詳細はシステムにより異なる。 例えば、Solaris 7 のマニュアルページでは、  呼び
       出し元の実ユーザ ID または実効ユーザ ID が 設定対象の実ユーザ ID か保存 (save) set-user-ID
       と 一致していなければならない、となっている。

       Linux では、 スケジューリングポリシーとスケジューリングパラメータは、 実際にはスレッド単位
       の属性である。 gettid(2) の呼び出しの返り値をこのシステムコールの pid 引き数として渡すこと
       ができる。 pid に 0 を指定すると、 呼び出し元のスレッドの属性が設定される。 getpid(2) コー
       ルからの返り値を   pid  に指定すると、  スレッドグループのメインスレッドの属性が設定される
       (POSIX   スレッド   API   を使用している場合は、    sched_*(2)    システムコールの代わりに
       pthread_setschedparam(3), pthread_getschedparam(3), and pthread_setschedprio(3) を使用する
       こと)。

       もともとは、標準の Linux は一般目的のオペレーティングシステムとして 設計されており、バック
       グラウンド・プロセスや対話的アプリケーション、  リアルタイム性の要求が厳しくないリアルタイ
       ム・アプリケーション (普通はタイミングの応答期限  (deadline)  を満たす必要があるアプリケー
       ション)  を扱うことができた。 Linux カーネル 2.6 では、 カーネルのプリエンプション (タスク
       の置き換え) が可能であり、 新たに導入された O(1) スケジューラにより、 アクティブなタスクの
       数に関わらずスケジューリングに必要な時間は 固定で確定的 (deterministic) であることが保証さ
       れている。 それにも関わらず、カーネル 2.6.17 までは 真のリアルタイム・コンピューティングは
       実現できなかった。

   本流の Linux カーネルでのリアルタイム機能
       カーネル  2.6.18 から現在まで、 Linux は徐々にリアルタイム機能を備えつつ あるが、 これらの
       機能のほとんどは、 Ingo Molnar, Thomas Gleixner, Steven Rostedt らによって開発された、  以
       前の realtime-preempt パッチ からのものである。 これらのパッチが本流のカーネルに完全にマー
       ジされるま では (マージの完了はカーネル 2.6.30 あたりの予定)、 最高のリアルタイム 性能を達
       成するには realtime-preempt パッチを 組み込まなければならない。 これらのパッチは

           patch-kernelversion-rtpatchversion

       という名前で、  ⟨http://www.kernel.org/pub/linux/kernel/projects/rt/⟩ からダウンロードでき
       る。

       このパッチが適用されず、かつパッチの内容の本流のカーネルへのマージが  完了するまでは、カー
       ネルの設定では  CONFIG_PREEMPT_NONE,  CONFIG_PREEMPT_VOLUNTARY,  CONFIG_PREEMPT_DESKTOP の
       3つのプリエンプション・クラス (preemption class) だけが提供される。 これらのクラスでは、最
       悪の場合のスケジューリング遅延がそれぞれ 全く減らない、いくらか減る、かなり減る。

       パッチが適用された場合、またはパッチの内容の本流のカーネルへのマージが  完了した後では、上
       記に加えて設定項目として CONFIG_PREEMPT_RT が利用可能になる。この項目を選択すると、  Linux
       は通常のリアルタイム・オペレーティングシステムに変身する。                  この場合には、
       sched_setscheduler()  で選択できる FIFO と RR のスケジューリング・ポリシーは、  真のリアル
       タイム優先度を持つスレッドを最悪の場合のスケジューリング遅延が  最小となる環境で動作させる
       ために使われることになる。

バグ

       POSIX では、成功時に sched_setscheduler()   は直前のスケジューリング・ポリシーを返すべきと
       されている。  Linux の sched_setscheduler()  はこの要求仕様に準拠しておらず、 成功時には常
       に 0 を返す。

関連項目

       chrt(1), getpriority(2), mlock(2), mlockall(2), munlock(2), munlockall(2), nice(2),
       sched_get_priority_max(2), sched_get_priority_min(2), sched_getaffinity(2),
       sched_getparam(2), sched_rr_get_interval(2), sched_setaffinity(2), sched_setparam(2),
       sched_yield(2), setpriority(2), capabilities(7), cpuset(7)

       Programming  for  the  real world - POSIX.4 by Bill O. Gallmeister, O'Reilly & Associates,
       Inc., ISBN 1-56592-074-0.

       Linux カーネルソースファイル Documentation/scheduler/sched-rt-group.txt

この文書について

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