この節では、スケジューラの構成を制御するパラメタとテーブルについて説明します。CPU、メモリー、入出力などのシステム資源の作業負荷が妥当であるものと仮定します。資源不足で需要を満たせない場合は、スケジューラを構成し直しても問題は解決しません。
dispadmin コマンドを使用すると、タイムシェアリングクラスとリアルタイムクラスに関して、実行中のシステム内のスケジューラパラメタを表示または変更 (微調整) できます。スケジューラ構成に永続的な変更を加えるには、それに該当するロード可能モジュール、つまり、ディレクトリ /kernel/sched 内の TS_DPTBL または RT_DPTBL 内で、スケジューラパラメタテーブルを変更しなければなりません。これらのモジュールを置き換える方法については、ts_dptbl(4) と rt_dptbl(4) のマニュアルページを参照してください。
プロセススケジューリングを制御する基本ユーザーコマンドは、priocntl(1) です。このコマンドを使用すると、ユーザーは指定した優先順位でプロセスを起動したり、実行中のプロセスの優先順位を操作したりできます。priocntl -l コマンドを使用すると、システム上で構成されているクラスを調べることができます。プロセススケジューリングを制御する基本関数コールは、priocntl(2) です。
priocntl コマンドの使用例については、第 63 章「プロセスの管理手順」を参照してください。リアルタイムプログラミング、dispadmin(1M) コマンド、priocntl(1) コマンドについての詳細は、『システムインタフェース』を参照してください。
次の表は、各スケジューラクラスのグローバル優先順位のスケジューリング順序と範囲を示しています。
表 67-1 スケジューリング順序とグローバル優先順位
スケジューリング順序 |
グローバル優先順位 |
スケジューラクラス |
---|---|---|
159 |
|
|
|
. |
|
|
. |
リアルタイム |
|
. |
|
|
100 |
|
|
|
|
|
. |
|
|
. |
システム |
|
. |
|
|
60 |
|
|
|
|
|
. |
|
|
. |
タイムシェアリング |
|
. |
|
最後 |
0 |
|
オペレーティングシステムが構築されるときに、この後の各節で説明する調整可能パラメタとスケジューラパラメタのテーブルから、グローバル優先順位を作成します。このグローバル優先順位テーブル全体を表示するコマンドはありません。ただし、dispadmin コマンドを使用すると、リアルタイムクラスとタイムシェアリングクラスに固有の優先順位 (0 から n まで) が表示されます。ps -cl コマンドを使用すると、有効なプロセスのグローバル優先順位を表示できます。
タイムシェアリングプロセスは、スケジューリングクラスと優先順位を親プロセスから継承します。init プロセスは、タイムシェアリングクラス全体で最初のプロセスです。
システムプロセスは、最初はプロセスの重要性 (カーネルにプログラムされている重要性) に応じた優先順位で実行されます。最も重要なシステムプロセスは、システムクラス範囲の最上位か、それに近い優先順位で開始されます。
この節では、スケジューラの構成を制御する調整可能パラメタについて説明します。これらのカーネルパラメタを変更するには、次の書式の 1 行を /etc/system ファイルに入力します。
set パラメタ=value
詳細は、system(4) のマニュアルページを参照してください。
この節で説明するパラメタは、プロセススケジューリング、タイムシェアリングポリシー、およびリアルタイムポリシーについて詳細に制御します。
リアルタイムプロセスの初期優先順位は、そのプロセスがリアルタイムスケジューリングクラスに入れられるときに決定されます。
priocntl -p コマンドを使用すると、リアルタイムクラス内で相対優先順位を指定できます。
これは、リアルタイムクラスの基本優先順位に追加されます。基本優先順位のデフォルトは 100 です。たとえば、
priocntl -e -c RT -p 20 command
上記のように入力すると、リアルタイム優先順位 120 でコマンドが実行されることになります。
次のカーネルパラメタは、プロセススケジューリングについて詳細に制御します。
maxclsyspri
maxclsyspri は、システムクラス内のプロセスの最大グローバル優先順位です。カーネルがシステムプロセスを起動するときに、参照ポイントとして maxclsyspri の値を使用して優先順位を割り当てます。カーネルはシステムクラスの優先順位全体の範囲が少なくとも 40 であると見なすので、maxclsyspri の値は 39 以上でなければなりません。
このパラメタを変更する場合は、割り当てる最大優先順位に対応する値を使用して、スケジューリングクラステーブルを再構築しなければなりません。
次のパラメタは、タイムシェアリングポリシーを制御するロード可能モジュール TS 内で指定します。
ts_maxupri
ts_maxupri は、ユーザーが priocntl(l) コマンドや priocntl(2) システムコールを使用してタイムシェアリングプロセスの優先順位を調整できる範囲を指定します。タイムシェアリングクラス内でユーザーが与える優先順位の有効な範囲は、+ts_maxupri から -ts_maxupri までです。ts_maxupri のデフォルト値は 20 です (この場合、古くてあまり一般的でないスケジューラインタフェース nice と setpriority の動作をエミュレートして、+20 から -20 までの範囲を設定します)。
ts_maxupri の値は、構成されているグローバルタイムシェアリング優先順位の数の影響を受けません。デフォルト構成では、0 から 59 までのタイムシェアリングポリシーがあります。しかし、ユーザーはシステムで計算されたプロセスの優先順位に対して、-20 から +20 までの範囲内でのみ優先順位を調整できます。詳細は、「優先順位を指定する方法」を参照してください。
このパラメタの値を変更するには、次の書式の 1 行を /etc/system に入力します。
set TS:ts_maxupri=value
次のパラメタは、リアルタイムポリシーを制御するロード可能モジュール RT 内で指定します。
rt_maxpri
rt_maxpri は、リアルタイムプロセスに割り当てる最大優先順位を指定します。rt_maxpri のデフォルト値は 159 です。
このパラメタを変更する場合は、割り当てる最大優先順位に対応する値を使用して、スケジューリングクラステーブルを再構築しなければなりません。
このパラメタの値を変更するには、次の書式の 1 行を /etc/system ファイルに入力します。
set RT:rt_maxupri=value
表 67-2 に、スケジューラテーブルを示します。
表 67-2 スケジューラテーブル
テーブル |
管理対象 |
---|---|
rt_dptbl |
リアルタイムプロセス |
ts_dptbl |
タイムシェアリングプロセス |
ts_kmdpris |
重要な資源を所有する休眠中のタイムシェアリングプロセス |
これらのテーブルは、リアルタイムプロセスとタイムシェアリングプロセスに使用するスケジューリングパラメタを設定して、スケジューリングポリシーを定義します。パラメタは、さまざまな優先レベルでプロセスが取得する CPU 時間の長さを指定します。
優先レベルのデフォルトのタイムスライスは、ts_dptbl 構成テーブルと rt_dptbl 構成テーブル内で指定されます。この 2 つのテーブルは、ロード可能モジュール TS_DPTBL および RT_DPTBL 内で定義されます。この 2 つのモジュールは、必要に応じてディレクトリ /kernel/sched からカーネルに自動的にロードされます。
タイムスライスは、「resolution」行で定義された解像度の単位数 (quanta) で指定されます。デフォルトの解像度は 1000 であり、タイムカンタムの値はミリ秒数として解釈されます。これは、秒数単位で指定された解像度の逆数から求められます。タイムスライスの quanta 量はクロックの目盛り単位でシステムクロックの解像度の次の積分倍数に切り上げられます (システムクロックの目盛りは 1 秒当たり HZ 回です。この場合、HZ は param.h ヘッダファイル内で定義されたハードウェア依存定数です)。たとえば、クロックの目盛りが 10 ミリ秒単位の場合は、タイムスライス量 42 quanta は切り上げられ 50 ミリ秒となります。
ts_dptb のデフォルトバージョンは、/kernel/sched/TS_DPTBL 内のシステムから配信されます。デフォルト構成では、タイムシェアリング優先順位は 60 です。
次の dispadmin -c TS -g コマンドでは、ts_dptbl テーブルの例を表示します。
$ dispadmin -c TS -g # Time Sharing Dispatcher Configuration RES=1000 # ts_quantum ts_tqexp ts_slpret ts_maxwait ts_lwait PRIORITY LEVEL 200 0 50 0 50 # 0 200 0 50 0 50 # 1 200 0 50 0 50 # 2 200 0 50 0 50 # 3 200 0 50 0 50 # 4 200 0 50 0 50 # 5 200 0 50 0 50 # 6 200 0 50 0 50 # 7 200 0 50 0 50 # 8 200 0 50 0 50 # 9 160 0 51 0 51 # 10 160 1 51 0 51 # 11 160 2 51 0 51 # 12 160 3 51 0 51 # 13 160 4 51 0 51 # 14 160 5 51 0 51 # 15 160 6 51 0 51 # 16 160 7 51 0 51 # 17 160 8 51 0 51 # 18 160 9 51 0 51 # 19 120 10 52 0 52 # 20 120 11 52 0 52 # 21 120 12 52 0 52 # 22 120 13 52 0 52 # 23 120 14 52 0 52 # 24 120 15 52 0 52 # 25 120 16 52 0 52 # 26 120 17 52 0 52 # 27 120 18 52 0 52 # 28 120 19 52 0 52 # 29 80 20 53 0 53 # 30 80 21 53 0 53 # 31 80 22 53 0 53 # 32 80 23 53 0 53 # 33 80 24 53 0 53 # 34 80 25 54 0 54 # 35 80 26 54 0 54 # 36 80 27 54 0 54 # 37 80 28 54 0 54 # 38 80 29 54 0 54 # 39 40 30 55 0 55 # 40 40 31 55 0 55 # 41 40 32 55 0 55 # 42 40 33 55 0 55 # 43 40 34 55 0 55 # 44 40 35 56 0 56 # 45 40 36 57 0 57 # 46 40 37 58 0 58 # 47 40 38 58 0 58 # 48 40 39 58 0 59 # 49 40 40 58 0 59 # 50 40 41 58 0 59 # 51 40 42 58 0 59 # 52 40 43 58 0 59 # 53 40 44 58 0 59 # 54 40 45 58 0 59 # 55 40 46 58 0 59 # 56 40 47 58 0 59 # 57 40 48 58 0 59 # 58 20 49 59 32000 59 # 59 $
表 67-3 に、ts_dptbl テーブル内のフィールドを示します。
表 67-3 ts_dptbl テーブル内のフィールド
フィールド名 |
説明 |
---|---|
ts_quantum (実行時) |
スケジューラが、あるプロセスの優先順位を評価し直す前に、そのプロセスを与えられた優先順位で実行できるタイムスライス (デフォルトではミリ秒単位) が入っている。プロセスがそのタイムスライス全体を使い果たすと、期間満了レベル (ts_tqexp) 待ち行列に入る。タイムスライスは、最上位の待ち行列の 40 ミリ秒 (59) から最下位の優先順位の 200 ミリ秒 (0) までになる。 |
ts_tqexp (期間満了レベル) |
タイムスライスが期間満了したプロセスの新しいプロセス優先順位を決定する。プロセスが休眠状態に入らずに全タイムスライスを使い果たすと、スケジューラはその優先順位を ts_tqexp カラムに示されたレベルに変更する。期間満了レベルは前のレベルよりも低くなる。たとえば、優先順位が 30 のプロセスがタイムスライス (80 ミリ秒) を使い果たすと、その新しい優先順位は 20 になる。 |
ts_slpret (休眠レベル) |
休眠状態から戻るときにプロセスに割り当てられる優先順位を決定する。プロセスは、特定のシステムコール中や、入出力の待機中 (ページフォルトのサービス中やロックの待機中など) に休眠状態になることがある。プロセスが休眠状態から戻るときは、常に優先順位 59 が与えられる。 |
ts_maxwait (待ち時間) |
タイムスライスが期間満了しない状態でプロセスがディスパッチ待ち行列に残っている秒数を指定する。タイムスライスを使用しない場合 (ts_maxwait 秒以内) 、その新しい優先順位は ts_lwait に設定される。これは、優先順位の低いプロセスが CPU 時間が不足するのを防ぐために使用される。 |
ts_lwait (待機レベル) |
タイムスライスを完全に取得しないまま最大待ち時間 (ts_maxwait) を超えた、実行準備ができているプロセスの新しい優先順位が入っている。 |
PRIORITY LEVEL |
グローバル優先順位が入っている。より上位の優先レベルで待ち行列に入ったプロセスが最初に実行される。グローバル優先順位は、上位の 59 から下位の 0 までになる。これは、調整できないテーブル内の唯一のカラムである。 |
rt_dptbl のデフォルトバージョンは、ロード可能モジュール/kernel/sched/RT_DPTBL 内でシステムと共に配信されます。
dispadmin -c RT -g コマンドは、次のような rt_dptbl 情報を表示します。
$ dispadmin -c RT -g # Real Time Dispatcher Configuration RES=1000 # TIME QUANTUM PRIORITY # (rt_quantum) LEVEL 1000 # 0 1000 # 1 1000 # 2 1000 # 3 1000 # 4 1000 # 5 1000 # 6 1000 # 7 1000 # 8 1000 # 9 800 # 10 800 # 11 800 # 12 800 # 13 800 # 14 800 # 15 800 # 16 800 # 17 800 # 18 800 # 19 600 # 20 600 # 21 600 # 22 600 # 23 600 # 24 600 # 25 600 # 26 600 # 27 600 # 28 600 # 29 400 # 30 400 # 31 400 # 32 400 # 33 400 # 34 400 # 35 400 # 36 400 # 37 400 # 38 400 # 39 200 # 40 200 # 41 200 # 42 200 # 43 200 # 44 200 # 45 200 # 46 200 # 47 200 # 48 200 # 49 100 # 50 100 # 51 100 # 52 100 # 53 100 # 54 100 # 55 100 # 56 100 # 57 100 # 58 100 # 59 $
表 67-4 に、リアルタイムパラメタテーブル内のフィールドを示します。
表 67-4 rt_dptbl テーブル内のフィールド
フィールド名 |
説明 |
---|---|
rt_glbpri |
グローバル優先順位が入っている。より上位の優先レベルで待ち行列に入ったプロセスが最初に実行される。dispadmin コマンドを使用するとテーブルを表示できるが、グローバル優先順位ではなくクラス内の相対優先順位しか表示されないので注意すること。このカラムを dispadmin で変更することはできない。 |
rt_qntm |
スケジューラが別のプロセスにチャンスを与える前に、この優先順位 (rt_glbpri) を持つプロセスを実行できるデフォルトのタイムスライス (ミリ秒単位) を示す。リアルタイムプロセスのタイムスライスは、priocntl -t コマンドで指定できる。 |
スケジューラは、カーネルモードのパラメタテーブル ts_kmdpris を使用して、休眠中のタイムシェアリングプロセスを管理します。ts_kmdpris のデフォルトバージョンは、ロード可能モジュール /kernel/sched/TS_DPTBL 内でシステムと共に配信され、システム構成の一部としてカーネルに自動的に組み込まれます。詳細は、ts_dptbl(4) のマニュアルページを参照してください。
カーネルは、ts_kmdpris 内に少なくとも 40 の優先順位があるものと想定します。40 の優先順位がないとパニックになります。
カーネルモードのパラメタテーブルは、60 から 99 までのグローバル優先順位の一次元配列です。プロセスが重要な資源を所有する場合は、できる限り短時間で資源を解放できるようにカーネル優先順位が割り当てられます。重要な資源は次のとおりです。
SunOS 5.3 より前のバージョンまでは、プロセスには休眠中にカーネル優先順位が割り当てられていました。これにより、待機中の資源が再び実行される前にページアウトされないことが保証されていました。
これを SunOS 5.3 以降のバージョンで実行するために、休眠状態から戻ったプロセスは、最上位のタイムシェアリング優先順位 (59) に変換されます。