kernel:schedule(1) / nice

  • Linuxのkernelでは、各アプリケーションをプロセスとして扱う
  • 複数のプロセスを同時に実行するため、プロセス実行の順序の整理などをkernelのスケジューラが行う
  • kernel2.6のスケジューラは優先度に基づく時分割実行を行う"Order One Scheduler(O(1)スケジューラ)"を採用している
  • 実行待ちプロセスを管理するRun QueueがCPUごとに用意される
  • 各Run Queueには、2種類の優先度付きQueueがある:active queueとexpired queue
  • どちらのQueueについても、140レベル(0〜139)の優先度に分かれており、優先度別に複数のプロセスを登録することができる
  • Active Queueには実行可能なプロセスが登録され、優先度に基づいて順次実行される
  • 各プロセスがCPUを使用できる時間をTime Slice/Quantumと呼ぶ
  • Time Sliceはプロセスごとに定義され、プロセスはQuantumで定義された間のみ処理を実行する
  • 割り当てられたTime Sliceで処理が完了できなかったプロセスはexpired queueに登録される
  • active queueに登録されたプロセスがすべて処理されると、expired queueとactive queueが切り替えられる(expired queueがactive queueに変更される)
  • プロセスの優先度を制御することにより、アプリケーションの処理性能を変化させることができる
  • プロセスの優先度は"nice値"という値により制御する
  • nice値で設定することができる値は-20〜19までの整数値であり、値が小さいほど優先度が高くなる
  • デフォルトのnice値は0
  • 現在実行中のプロセスのnice値を確認するには、"ps -lax"コマンドを使用する

NIがnice値を示す

[root@tkcent1 include]# ps -lax
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.7/FAQ
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
4     0     1     0  20   0  10316   660 -      Ss   ?          0:00 init [3]                                   

nice値を変更する方法は、コマンドによる設定とソースコードに関数を埋め込む方法がある

  • reniceコマンド
  • 実行中のプロセスのnice値を変更するコマンド
  • スーパーユーザはすべてのプロセス、一般ユーザは自信が所有するプロセスのnice値を「下げる」ことだけが可能
  • プロセスIDに対して設定するnice値を指定する

プロセスID50のnice値を10に変更する例

# renice 10 -p 50

実際にやってみた(topプロセスをバックエンドで実行して、そのnice値を変更してみる)

[root@tkcent1 include]# top &
[1] 14523
[root@tkcent1 include]# ps lax | grep 14523
0     0 14523  2991  20   0  10488   696 finish T    pts/0      0:00 top
0     0 14525  2991  20   0  64520   800 pipe_w S+   pts/0      0:00 grep 14523

[1]+  Stopped                 top
[root@tkcent1 include]# renice 10 -p 14523
14523: old priority 0, new priority 10
[root@tkcent1 include]# 
[root@tkcent1 include]# ps lax | grep 14523
0     0 14523  2991  30  10  10488   696 finish TN   pts/0      0:00 top
0     0 14530  2991  20   0  64520   800 pipe_w S+   pts/0      0:00 grep 14523
[root@tkcent1 include]# 
  • niceコマンド

プロセスの起動時にnice値を設定することもできる
実際にやってみた(普通に実行した場合とniceコマンドでnice値を指定して実行した場合の違いを確認する)

[root@tkcent1 include]# top &
[1] 14558
[root@tkcent1 include]# nice -n 5 top &
[2] 14559

[1]+  Stopped                 top
[root@tkcent1 include]# ps lax | grep top
0     0 14558  2991  20   0  10488   696 finish T    pts/0      0:00 top
0     0 14559  2991  25   5  10488   696 finish TN   pts/0      0:00 top
0     0 14561  2991  20   0  64520   804 pipe_w S+   pts/0      0:00 grep top

[2]+  Stopped                 nice -n 5 top
[root@tkcent1 include]# 
  • プログラムにnice値を埋め込む場合は、プログラムのソースコードで nice (); 関数を記述してコンパイルする
  • nice関数の記述はプログラムのどこでもかまわなく、nice関数が実行された時点でnice値の変更が実行される(優先度が変化する)
  • 一般ユーザが実行するプログラムではnice関数がある場合でも初期値より大きな値にすることしかできず、一度設定したnice値より小さい値に再設定することもできない
  • スーパーユーザが実行するプログラムではnice関数を使用することにより優先度を上げることができる
  • コマンドによる方法でも、関数を埋め込む方法でも、対象のプロセスによって生成される子プロセスは親プロセスのnice値を継承する