kazmax - Linux で自宅サーバー

sched_setscheduler - システムコールの説明 - Linux コマンド集 一覧表

  1. 名前
  2. 書式
  3. 説明
  4. 返り値
  5. エラー
  6. 準拠
  7. 注意
  8. 関連項目

名前

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 によって識別されるプロセスのスケジューリング方針や それに関連するパラメータを設定する。pid が 0 の場合は 呼び出したプロセスのスケジューリングが設定される。 パラメータ param の解釈は選択された方針による。 現在のところ、Linux では SCHED_FIFO , SCHED_RR , SCHED_OTHER , SCHED_BATCH のスケジューリング方針がサポートされている。 それぞれの方式については以下で述べる。
sched_getscheduler ()は pid で識別されるプロセスに現在適用されている スケジューリング方針を尋ねる。pid が 0 ならば、呼び出した プロセス自身のスケジューリング方針が返される。

スケジューリング方針 (scheduling policy)

スケジューラ (scheduler) とはカーネルの一部で、次に CPU で実行される 実行可能なプロセスを決定するものである。 Linux のスケジューラーは三つの異なるスケジューリング方針を提供しており、 一つは通常のプロセス用、二つはリアルタイム・アプリケーション用である。 全てのプロセスには 静的優先度 (static priority) sched_priority が割り当てられ、 この値はシステム・コールを通してのみ変更できる。 sched_priority は 0 から 99 の範囲の値を取ることができ、 スケジューラはその sched_priority の値それぞれに対して 実行可能なプロセスのリストを管理している。次に実行するプロセスを 決定するために、Linux のスケジューラは静的優先度の最も高い 空でないリストを探して、そのリストの先頭のプロセスを取り出す。 スケジューリング方針はそれぞれのプロセスが同じ静的優先度を持つ プロセスのリストの中のどこに挿入され、このリストの中をどのように 移動するかを決定する。
SCHED_OTHER はデフォルトの一般的な時分割型スケジューリング方針で、 多くのプロセスによって使用される。 SCHED_BATCH はプロセスの「バッチ」タイプの実行を目的と したものである。 SCHED_FIFOSCHED_RR はどの実行可能プロセスを選択するか について、より正確な制御を必要とする時間の制約が厳しい特殊な アプリケーションのためのものである。
SCHED_OTHERSCHED_BATCH でスケジューリングされている プロセスは静的優先度として 0 が指定されなければならない。 SCHED_FIFOSCHED_RR でスケジューリングされているプロセスは 1 から 99 の範囲の 静的優先度を取ることができる。 sched_get_priority_min () と sched_get_priority_max () システム・コールを使用することで全ての POSIX.1-2001 互換システムに 移植可能な方法で有効な優先度の範囲を取得することができる。
全てのスケジューリングはプリエンプティブ (preemptive) である: より高い優先度のプロセスの実行の準備ができると、現在のプロセスは 優先的なものに置きかえられ (preempted)、待ちリストへ戻される。 スケジューリング方針は同じ静的優先度を持つ実行可能なプロセスの リストの中で順番のみを決定する。

SCHED_FIFO: ファーストイン・ファーストアウト・スケジューリング

SCHED_FIFO は 0 より大きな静的優先度でのみ使用でき、 SCHED_FIFO プロセスが実行可能になった場合、すぐに、現在実行している SCHED_OTHERSCHED_BATCH プロセスと置き換えられる。 SCHED_FIFO は時分割のない単純なスケジューリング・アルゴリズムである。 SCHED_FIFO 方針でスケジューリングされているプロセスには以下の 規則が適用される: より高い優先度の他のプロセスによって置きかえられた SCHED_FIFO プロセスはその優先度のリストの先頭に留まり続け、 より高い優先度のプロセス全てが停止 (block) した場合には再び実行を続ける。 SCHED_FIFO プロセスが実行可能になった時、その優先度のリストの最後 に挿入される。sched_setscheduler () や sched_setparam () は pid で指定された SCHED_FIFO (または SCHED_RR ) プロセスが 実行可能な場合、リストの最初に置く。 結果として、もしプライオリティが同じだった場合、 現在実行中のプロセスに先んじるかもしれない。 (POSIX.1-2001 ではプロセスはリストの最後に行くべきと規定されている。) sched_yield () を呼び出したプロセスはリストの 最後に置かれる。その他のイベントによって SCHED_FIFO 方針で スケジューリングされるプロセスが同じ優先度の実行可能なプロセスの 待ちリストの中を移動することはない。SCHED_FIFO プロセスは I/O 要求によって停止するか、より高い優先度のプロセスによって置き かえられるか、sched_yield () を呼び出すまで実行を続ける。

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 でのみ使用できる。 この方針は SCHED_OTHER と似ているが、この方針ではスケジューラが プロセスが常に CPU に負荷のかかる (CPU-intensive) 処理を行うと仮定する 点が異なる。結果として、スケジューラはそのプロセスにスケジューリング上 のペナルティを少し課し、このプロセスはスケジューリングの決定で若干 冷遇されるようになる。 この方針は、非対話的な処理だがその nice 値を下げたくない処理や、 (処理のタスク間で) 余計なタスクの置き換えの原因とある対話的な処理なしで 確定的な (deterministic) スケジューリング方針を適用したい処理に 対して有効である。

特権とリソース制限

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 と 一致している場合に限られる。 RLIMIT_RTPRIO に関するもっと詳しい情報は   getrlimit (2) を参照のこと。 特権プロセス ( CAP_SYS_NICE ケーパビリティを持つプロセス) の場合、この制限は無視される; 古いカーネルと同じように、スケジューリング方針と優先度に対し 任意の変更を行うことができる。

応答時間 (response time)

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

その他

子プロセスは fork ()の際に親プロセスのスケジューリング・アルゴリズムを継承する。   execve (2) の前後で、スケジューリング・アルゴリズムとパラメータは保持される。
リアル・タイム・プロセスは大抵、ページングの待ち時間を避けるために mlock ()や mlockall ()を使ってメモリ・ロックをしなければならない。
SCHED_FIFOSCHED_RR でスケジューリングされる プロセスが停止せずに無限ループにおちいると、 他の全てのより低い優先度のプロセスを永久に停止 (block) させてしまうので、 ソフトウェア開発者はコンソールのシェルの静的優先度をテストする アプリケーションよりも常に高く保つべきである。 これによって期待通りに停止したり終了したりしないリアル・タイム・ アプリケーションを緊急終了させることが可能になる。
POSIX システムでは <unistd.h> に _POSIX_PRIORITY_SCHEDULING が定義されている場合にのみ sched_setscheduler ()と sched_getscheduler ()が使用できる。

返り値

成功した場合、 sched_setscheduler ()は 0 を返す。 成功した場合、 sched_getscheduler ()は現在のそのプロセスの方針 (非負の整数) を返す。 エラーの場合、-1 が返され、 errno が適切に設定される。

エラー

EINVAL
スケジューリング方針 policy が間違っているか、 パラメータ param がその方針では意味をなさない。
EPERM
呼び出したプロセスが適切な特権を持っていない。
ESRCH
IDが pid のプロセスが見つからない。

準拠

POSIX.1-2001. SCHED_BATCH 方針は Linux 固有である。

注意

標準的な Linux は一般目的のオペレーティングシステムなので、 バックグラウンド・プロセスや、対話的アプリケーション、 ソフト・リアルタイム(soft real-time)・アプリケーション (普通のタイミングの応答期限 (deadline) が必要なアプリケーション) を扱える。

標準的な Linux は (しばしば 1秒以下の) 期限を保証する必要があったり、 失敗が破滅的な事態を引き起こすハード・リアルタイム (hard real-time)・ アプリケーションをサポートするようには 設計されていない。 他の全ての一般目的のオペレーティングシステムと同様に Linux は 最悪時のパフォーマンスではなく 平均的なパフォーマンスを最大化するようにデザインされている。 Linux の最悪の場合の割り込み処理は平均的な場合に比べて大きく劣っている。 (SMP のためのロックのような) さまざまなカーネルロックは長い最長待ち時間 を引き起こす。また平均時間を減らすために開発された多数のパフォーマンス 改良技術によって最悪時の時間は増加する。 多くの状況ではこれがあなたの望む動作だろう。しかしもし本当に ハード・リアルタイム・アプリケーションを開発している場合には RTLinux (http://www.rtlinux.org) や RTAI (http://www.rtai.org) のようなリアルタイム拡張された Linux や厳しいリアル・タイムアプリケーション専用に設計された 他の OS の使用を考慮すべきである。

関連項目

  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) 

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