Linux の 101 試験対策: プロセス実行の優先度

現在の進行状況を監視する

アプリケーションが必要とする処理時間を十分確保できるように、プロセスの優先度を設定および変更する方法を学んでください。この記事の内容は、Linux のシステム管理者として認定するための LPI® 101 試験に備えるためにも、自ら活用するために学ぶ上でも役立ちます。

Ian Shields, Senior Programmer, IBM

Ian ShieldsIan Shields は、developerWorks Linux ゾーンの様々な Linux プロジェクトに関わっています。彼はノースキャロライナ州 Research Triangle Park にある IBM のシニア・プログラマーです。1973年にオーストラリアのキャンベラでシステム・エンジニアとして IBM に入社して以来、カナダのモントリオールやノースキャロライナ州 Research Triangle Park で、コミュニケーション・システムやパーベイシブ・コンピューティングに携わってきました。彼はいくつかの特許を保持しています。Australian National University にて純粋数学および哲学で学位を取得し、また North Carolina State University にてコンピューター・サイエンスで修士号と博士号を取得しています。Ian について詳しく知るには、My developerWorks で彼のプロフィールを見てください。


developerWorks 貢献著者レベル

2010年 2月 02日

この連載について

この連載は Linux システム管理タスクの学習に役立つだけでなく、LPIC-1 (Linux Professional Institute Certification レベル 1) 試験に備えるための教材にもなります。

連載の各記事についての説明とリンクについては、連載のロードマップを参照してください。現在進行中のこのロードマップは、LPIC-1 試験の最新の目標 (2009年4月) を反映しています。完成した記事はその都度ロードマップに追加されていきますが、当面は developerWorks の LPI 認定試験対策チュートリアルで同様の教材の以前のバージョンを調べてください。これらのバージョンは、2009年4月より前の LPIC-1 目標に対応しています。

概要

この記事では、実行プロセスの優先度を管理するための基本的な Linux の手法を説明します。この記事で説明する内容は以下のとおりです。

  • プロセスの優先度について
  • プロセスの優先度を設定する方法
  • プロセスの優先度を変更する方法

この記事は、Linux Professional Institute の Junior Level Administration (LPIC-1) 101 試験の主題 103 の 103.6 の試験対策となります。この目標の重要度は 2 です。

前提条件

この連載の記事を最大限に活用するには、Linux の基礎知識と、記事に記載されたコマンドを演習できる実際の Linux システムが必要です。プログラムのバージョンによって出力のフォーマットに違いが出てくる場合もあるため、コマンドの実行結果は必ずしもここに記載するリストや図とまったく同じであるとは限りません。記載するサンプル・コードの結果は、Ubuntu 9.10 (Karmic Koala) ディストリビューションで実行して得られたものです。この記事は、以前の記事「Linux の 101 試験対策: プロセスの作成、モニター、およびプロセスへのシグナル送信」で説明した概念をベースに作成されています。


優先度について

Ian とつながるには

Ian は developerWorks で人気の高いお馴染みの著者の 1 人です。Ian が書いたすべての developerWorks 記事を閲覧してみてください。また、My developerWorks では、Ian のプロフィールを調べることや、彼やその他の著者、そして他の読者とつながることができます。

Linux は最近のほとんどのオペレーティング・システムと同じく、複数のプロセスを実行することができます。Linux では CPU とその他のリソースをプロセス間で共有することで、それを実現します。そのため、あるプロセスが CPU の 100% を使用できるとしたら、他のプロセスは応答しなくなる可能性があります。

top コマンドを実行すると、デフォルトでは CPU 使用率の高い順にプロセスが一覧表示されます (リスト 1 を参照)。以前の記事「Linux の 101 試験対策: プロセスの作成、モニター、およびプロセスへのシグナル送信」では、簡単な時計のスクリプトを紹介しました。このスクリプトはコンソールに 30 秒ごとに時刻を表示する以外のことは何もしません。このプロセスを実行したとしても、top コマンドによって出力される一覧に、このプロセスは表示されないはずです。その理由は、このプロセスは CPU を使用していない時間のほうが遥かに多いためです。

リスト 1. Linux ワークステーションで top コマンドを実行したときの典型的な出力結果
top - 08:00:52 up 1 day, 10:20,  5 users,  load average: 0.04, 0.08, 0.04
Tasks: 172 total,   1 running, 171 sleeping,   0 stopped,   0 zombie
Cpu(s):  3.7%us,  0.3%sy,  0.0%ni, 95.6%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   4057976k total,  1777976k used,  2280000k free,   225808k buffers
Swap: 10241428k total,        0k used, 10241428k free,   655796k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND            
11220 ian       20   0  555m 106m  27m S    8  2.7  36:06.16 firefox            
    7 root      15  -5     0    0    0 S    1  0.0  10:59.36 ksoftirqd/1        
10849 ian       20   0  212m  15m  10m S    0  0.4   0:08.11 gnome-terminal     
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.83 init               
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd           
    3 root      RT  -5     0    0    0 S    0  0.0   0:00.02 migration/0        
    4 root      15  -5     0    0    0 S    0  0.0   0:01.08 ksoftirqd/0        
    5 root      RT  -5     0    0    0 S    0  0.0   0:00.00 watchdog/0         
    6 root      RT  -5     0    0    0 S    0  0.0   0:00.03 migration/1

お使いのシステムには、大量の CPU リソースを消費する可能性のあるコマンドが多数あるはずです。例えば、動画の編集ツール、画像ファイルの形式を変換するプログラム、そして音声の圧縮方式を (例えば mp3 から ogg へ) 変換するプログラムなどが相当します。

CPU が 1 つしかない場合や、CPU の数が限られている場合には、その限られた CPU リソースを競合する複数のプロセス間で共有する方法を決めなければなりません。それには通常、実行するプロセスを 1 つ選び、そのプロセスを短期間 (タイムスライスと呼ばれる時間) 実行するか、あるいは何らかのイベント (入出力の完了など) を待機する必要が生じるまで実行するという方法が採られます。CPU リソースを大量に消費する他のプロセスによって重要なプロセスが CPU を使用できなくなるという状況を確実に回避するために、実行するプロセスの選択は、スケジューリング優先度に基づいて行われます。上記のリスト 1 に示された NI 列に表示されているのが、各プロセスのスケジューリング優先度、つまり nice 値です。nice 値の範囲は通常 -20 から 19 までで、-20 がスケジューリング対象として最も望ましい (最高優先度の) プロセス、19 が最も望ましくない (最低優先度の) プロセスとなります。

ps による nice 値の調査

nice 値を表示するには、top コマンドだけでなく、ps コマンドも使用することができます。記事「Linux の 101 試験対策: プロセスの作成、モニター、およびプロセスへのシグナル送信」で説明した方法で出力をカスタマイズすることもできますし、詳細な情報を表示するための -l オプションのみを指定することもできます。リスト 2 に記載するのは、ps -l を実行した場合の出力です。top コマンドと同じく、nice 値は NI 列で調べられます。

リスト 2. ps による nice 値の調査
ian@attic4:~$ ps -l
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1000 26502 26501  0  80   0 -  5368 wait   pts/4    00:00:00 bash
0 R  1000 27046 26502  0  80   0 -  1684 -      pts/4    00:00:00 ps

デフォルトの nice 値

リスト 1 やリスト 2 から察しがつくと思いますが、少なくとも一般ユーザーが開始したプロセスの場合には、nice 値はデフォルトで 0 に設定されます。現在の Linux システムでは、これが一般的なデフォルト設定です。お使いのシェルおよびシステムで、このデフォルト値を確認するには、パラメーターを指定せずに nice コマンドを実行します (リスト 3 を参照)。

リスト 3. デフォルトの nice 値の確認
ian@attic4:~$ nice
0

優先度の設定

nice 値を設定または変更する方法の説明に入る前に、nice 値が実際にどのように機能するかを説明するため、CPU リソースを大量に使用する簡単なスクリプトを作成します。

CPU リソースを大量に使用するスクリプト

これから、CPU を使用することだけが目的の、他にはほとんど何もしない簡単なスクリプトを作成します。このスクリプトが入力として取るのは、カウントとラベルの 2 つです。スクリプトはまずラベルと現在の日付と時刻を出力した後、ループに入ってカウントが 0 になるまでデクリメントしていき、最後にラベルと日付をもう一度出力します。リスト 4 に記載するように、このスクリプトではエラーのチェックを行わないため、あまり堅牢なスクリプトではありませんが、これから説明しようとしているポイントは明らかになります。

リスト 4. CPU リソースを大量に使用するスクリプト
ian@attic4:~$ echo 'x="$1"'>count1.sh
ian@attic4:~$ echo 'echo "$2" $(date)'>>count1.sh
ian@attic4:~$ echo 'while [ $x -gt 0 ]; do x=$(( x-1 ));done'>>count1.sh
ian@attic4:~$ echo 'echo "$2" $(date)'>>count1.sh
ian@attic4:~$ cat count1.sh
x="$1"
echo "$2" $(date)
while [ $x -gt 0 ]; do x=$(( x-1 ));done
echo "$2" $(date)

上記のスクリプトをお使いのシステムで実行すると、リスト 5 のような出力が表示されるはずです。システムの処理速度によっては、時間の差が確認できるようにカウントの値を大きくする必要があるかもしれません。この後すぐに明らかになりますが、このスクリプトは大量の CPU リソースを使用します。デフォルトのシェルが Bash ではなく、このスクリプトが実行できない場合には、以下に記載する 2 番目の方法でスクリプトを呼び出してください。自分が所有するワークステーション以外の環境でスクリプトを実行する場合、必ず大量の CPU を使用する許可をもらってください。

リスト 5. count1.sh の実行
ian@attic4:~$ sh count1.sh 10000 A
A Wed Jan 20 08:34:16 EST 2010
A Wed Jan 20 08:34:16 EST 2010
ian@attic4:~$ bash count1.sh 99000 A
A Wed Jan 20 08:34:20 EST 2010
A Wed Jan 20 08:34:22 EST 2010

ここまでのところ、順調です。今度はコマンド・リストを作成してバックグラウンドでこのスクリプトを実行した上で top コマンドを実行し、スクリプトがどれだけの CPU リソースを使用しているかを確認してみます (コマンド・リストについて復習するには、以前の記事「Linux の 101 試験対策: Linux コマンドライン」を参照してください)。リスト 6 にコマンド・リストを、リスト 7 に top コマンドによる出力を記載します。

リスト 6. count1.sh と top の実行
ian@attic4:~$ (sh count1.sh 5000000 A&);top
リスト 7. 大量の CPU リソースの使用
top - 15:41:15 up 1 day, 17:59,  6 users,  load average: 0.20, 0.06, 0.02
Tasks: 169 total,   2 running, 167 sleeping,   0 stopped,   0 zombie
Cpu(s): 52.1%us,  0.7%sy,  0.0%ni, 47.3%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   4057976k total,  1393772k used,  2664204k free,   235596k buffers
Swap: 10241428k total,        0k used, 10241428k free,   662592k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
26756 ian       20   0  4004  588  496 R  100  0.0   0:03.53 sh
11220 ian       20   0  555m 101m  27m S    5  2.6  57:58.07 firefox
26757 ian       20   0 19132 1364  980 R    0  0.0   0:00.03 top
    1 root      20   0 19584 1888 1196 S    0  0.0   0:00.89 init
    2 root      15  -5     0    0    0 S    0  0.0   0:00.01 kthreadd

悪くない結果です。以上のように、たった 1 つの簡単なスクリプトだけで、このシステムに搭載されている CPU のうちの 1 つを 100% 占有しています。複数の CPU に負荷をかけたい場合には、コマンド・リストに count1.sh の呼び出しをもう 1 つ追加してください。このスクリプトのように長時間実行されるジョブがシステム上にある場合、そのジョブによって、自分や他のユーザーがシステム上で他の作業を行えなくなる可能性があります。

nice による優先度の設定

これで CPU をしばらくビジー状態にしておけるようになったので、これからプロセスの優先度を設定する方法を説明します。以下に、これまでに学んだ内容をまとめます。

  • Linux および UNIX® システムは、-20 (最高優先度) から 19 (最低優先度) までの 40 段階の優先度方式を使用します。
  • 通常、一般ユーザーが開始したプロセスの優先度は 0 に設定されます。
  • 優先度 (nice、NI、レベルなど) を表示するには、-l オプションを指定して ps コマンドを実行します。
  • nice コマンドによってデフォルトの優先度が表示されます。

nice コマンドは、優先度を変えてプロセスを開始するために使用することもできます。-n (または --adjustment) オプションに続けて、正の値を指定するとデフォルトよりも優先度の値が高くなり、負の値を指定すると優先度の値が下がります。前述したとおり、優先度の値が最低のプロセスは最高のスケジューリング優先度で実行されるので、優先度の値を増やすということは、他のプロセスに親切 (nice) にすることだと考えてください。注意する点として、負の値の優先度を指定できるのは、通常はスーパーユーザー (root) のみです。つまり、一般ユーザーは自分のプロセスの優先度を下げることしかできません。

nice を使用して優先度を設定する方法を説明するため、これから count1.sh スクリプトの 2 つのコピーを異なるサブシェルで同時に実行します。ただし、一方のコピーには最大の nice 値 19 を指定します。その後すぐに、ps -l を使用して nice 値を含めたプロセスの状況を表示します。最後に任意の 30 秒間のスリープを追加し、2 つのサブシェルが完了した後にコマンド・シーケンスが完了するようにします。こうすることで、出力の待機中に新しいプロンプトが出されなくなるためです。この結果を、リスト 8 に記載します。

リスト 8. nice を使用して 2 つのプロセスに優先度を設定した場合の出力
ian@attic4:~$ (sh count1.sh 2000000 A&);(nice -n 19 sh count1.sh 2000000 B&);\
> sleep 1;ps -l;sleep 10
A Thu Jan 21 14:38:39 EST 2010
B Thu Jan 21 14:38:39 EST 2010
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1000   946     1 99  80   0 -  1001 -      pts/3    00:00:01 sh
0 R  1000   948     1 99  99  19 -  1001 -      pts/3    00:00:01 sh
0 R  1000   952 32408  0  80   0 -  1684 -      pts/3    00:00:00 ps
0 S  1000 32408 32407  0  80   0 -  5368 wait   pts/3    00:00:02 bash
A Thu Jan 21 14:38:45 EST 2010
B Thu Jan 21 14:38:45 EST 2010

2 つのジョブが同時に完了したことに驚きましたか?優先度の設定はどうなったのかと言うと、このスクリプトは CPU のうちの 1 つを占有していたことを思い出してください。AMD Athlon™ 7750 デュアル・コア・プロセッサー上で稼働するこのシステムには、ほんのわずかな負荷しかかかりません。各コアが 1 つのプロセスを実行するため、2 つのプロセスに優先度を設定する必要はなかったというわけです。

そこで、今度は 4 つのプロセスをそれぞれに異なる nice 値 (0、6、12、および 18) で開始して、どのような結果になるかを見てみましょう。プロセスの実行時間を少し長くするため、各プロセスのビジー・カウント・パラメーターは増やします。リスト 9 を見る前に、これまでに学んだ内容を踏まえて結果を予想してみてください。

リスト 9. nice を使用して 4 つのプロセスの優先度を設定した場合の出力
ian@attic4:~$ (sh count1.sh 5000000 A&);(nice -n 6 sh count1.sh 5000000 B&);\
> (nice -n 12 sh count1.sh 5000000 C&);(nice -n 18 sh count1.sh 5000000 D&);\
> sleep 1;ps -l;sleep 30
A Thu Jan 21 16:06:00 EST 2010
C Thu Jan 21 16:06:00 EST 2010
D Thu Jan 21 16:06:00 EST 2010
B Thu Jan 21 16:06:00 EST 2010
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 R  1000  1422     1 94  80   0 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1424     1 42  86   6 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1427     1 56  92  12 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1431     1 14  98  18 -  1001 -      pts/3    00:00:00 sh
0 R  1000  1435 32408  0  80   0 -  1684 -      pts/3    00:00:00 ps
0 S  1000 32408 32407  0  80   0 -  5368 wait   pts/3    00:00:02 bash
A Thu Jan 21 16:06:14 EST 2010
B Thu Jan 21 16:06:17 EST 2010
C Thu Jan 21 16:06:26 EST 2010
D Thu Jan 21 16:06:30 EST 2010

上記の出力から、4 つの異なる優先度を設定した場合には、nice 値の影響により、それぞれのジョブが優先度の順に完了していることがわかります。他にも異なる nice 値を試して、考えられるさまざまな結果を自分の目で確かめてください。

nice でプロセスを開始する場合の最後の注意点として、nohup コマンドと同じく、nice の引数にはコマンド・リストやパイプラインを使用することはできませんのでご注意ください。


優先度の変更

renice

プロセスを開始した後に、別の優先度で実行しなければならないことに気付いた場合、プロセス開始後にその優先度を変更する方法があります。それは、renice コマンドを使用する方法です。このコマンドを使用して、変更対象の 1 つまたは複数のプロセスに絶対優先度 (調整値ではありません) を指定します (リスト 10 を参照)。

リスト 10. renice による優先度の変更
ian@attic4:~$ sh count1.sh 10000000 A&
[1] 1537
ian@attic4:~$ A Thu Jan 21 16:17:16 EST 2010
sh count1.sh 1renice 1 1537;ps -l 1537
1537: old priority 0, new priority 1
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
0 R  1000  1537 32408 99  81   1 -  1001 -      pts/3      0:13 sh count1.sh 100
ian@attic4:~$ renice +3 1537;ps -l 1537
1537: old priority 1, new priority 3
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY        TIME CMD
0 R  1000  1537 32408 99  83   3 -  1001 -      pts/3      0:18 sh count1.sh 100

renice の場合も、スーパーユーザーでないと、プロセスのスケジューリング優先度を上げるために nice 値を小さくすることはできません。

nice および renice についての詳細は、man ページに記載されています。

参考文献

学ぶために

製品や技術を入手するために

  • developerWorks から直接ダウンロードできる IBM ソフトウェアの試用版を使用して、Linux で次の開発プロジェクトを構築してください。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=470176
ArticleTitle=Linux の 101 試験対策: プロセス実行の優先度
publish-date=02022010