第6章 実行中のプロセスを管理する
Linuxって、マルチユーザーOSで、マルチタスクシステムでもあるんだ。マルチタスクってことは、複数のプログラムを同時に動かせるってこと。この動いてるプログラムのインスタンスのことを、通常「プロセス」って呼ぶんだよ。
シェルからプロセスを起動したり、一時停止させたり、停止させたり、強制終了させたりできるんだ。それに、プロセスをバックグラウンドに置いたり、フォアグラウンドに戻したりもできるよ。
6.1 プロセスを理解しよう
プロセスっていうのは、コマンドが実行されたインスタンスのこと。システム中のプロセスは、プロセスID (PID) っていうので識別されてて、このPIDは現在のシステム上でユニークなんだ。PID以外にも、プロセスは特定のユーザーアカウントやグループアカウントと紐づいてて、そのプロセスがどんなシステムリソースにアクセスできるかを判断するのに役立つんだ。
プロセス関連の情報を表示するコマンドは、主に/procファイルシステムに保存されてる生データから情報を取得してるよ。各プロセスは/proc内のサブディレクトリ(そのプロセスのPIDが名前になってる)に自分の情報を保存してるんだ。
6.2 プロセスの一覧表示
psコマンドかtopコマンドを使うんだ。topコマンドの方が、より画面に特化した形でプロセスを一覧表示してくれるよ。
6.2.1 psコマンドでプロセスを一覧表示しよう
ps uを使うと、ユーザー名とか他の情報も表示してくれるよ。
VSZ:仮想メモリサイズ (Virtual Set Size) で、イメージプロセスのサイズ(単位:KB)を表示するんだ。
RSS:(Resident Set Size) で、メモリ中のプログラムのサイズを表示するよ。
VSZはプロセスに割り当てられたメモリ量で、RSSはプロセスが実際に使ってるメモリ量(スワップできない物理メモリのこと)を表してるんだ。
STAT列:Sは現在実行中のプロセス、Rはスリープ中のプロセス、+はプロセスがフォアグラウンド操作と関連してることを示すんだ。
現在のユーザーの全プロセスを見るには:ps ux | less
全ユーザーのプロセスを見るには:ps aux | less
出力列をカスタマイズしたり、特定の列でソートしたりもできるよ。例えばこんな感じ。
| |
-eは実行中の全プロセスを表示するオプションで、-oの後ろには表示する列を指定するんだ。commはコマンドで、--sort=-vszはvsz列で大きい順にソートするって意味だよ。
6.2.2 topコマンドでプロセスを一覧表示・変更しよう
topコマンドを使うと、デフォルトではプロセスが現在使ってるCPUの割合でソートされて表示されるんだ。
topコマンドでできる操作はこれ!
| コマンド | 説明 |
|---|---|
| h | ヘルプ |
| M | メモリ使用状況でソート |
| 1 | 全CPUの使用状況表示を切り替え (システムに複数のCPUがある場合) |
| R | 逆順ソート |
| u | その後ユーザー名を入力すると、そのユーザーのプロセスを表示 |
| r | プロセスの優先度を変更 (nice値) |
| k | プロセスを強制終了 (killコマンド) |
6.2.3 System Monitorでプロセスを一覧表示しよう
GNOMEデスクトップのGUIツールだよ。
6.3 バックグラウンドとフォアグラウンドのプロセスを管理しよう
GUIがないシステムだと、全部シェルで操作するしかないよね。Bashシェルには複数のプログラムを管理するGUIはついてないけど、アクティブなプログラムをバックグラウンドとフォアグラウンドで直接移動させることができるんだ。こうすれば、たくさんのプログラムを動かしつつ、今やりたいプログラムを選んで作業できるってわけ。
6.3.1 バックグラウンドプロセスを起動しよう
コマンドをバックグラウンドに置くには:
コマンドの後ろに
&をつけるatコマンドを使って他のコマンドを実行する実行中のプロセスに対しては、Ctrl+Zで停止させて、それから
fgでフォアグラウンドに戻すか、bgでバックグラウンドで実行を再開させる
バックグラウンドの出力がフォアグラウンドの操作を邪魔しないように、空のデバイス
2>/dev/nullにリダイレクトすることもできるよ。
jobsコマンドでバックグラウンドで動いてるコマンドを確認できるよ(-lを使うとPIDも見れる)。コマンド番号の前に+がついてるのは最近バックグラウンドに置かれたジョブで、-がついてるのはその前に置かれたジョブなんだ。
6.3.2 フォアグラウンドとバックグラウンドのコマンドを使ってみよう
バックグラウンドジョブを参照したいなら、%とジョブ番号(jobsコマンドの出力)を使うんだ。他にもこんな方法があるよ。
%— 最近バックグラウンドに置かれたジョブ(つまり番号の後ろに+がついてるやつ)を参照する%string— stringで始まるジョブ(あいまいだとダメ、つまり一致結果がユニークじゃないと)%?string— コマンドラインのどこかにstringが含まれるジョブ(これもあいまいだとダメ、一致結果がユニークじゃないと)%--— 最近バックグラウンドに置かれたジョブの前に置かれたジョブ(つまり番号の後ろに-がついてるやつ)を参照する
fg %1を使うと、番号1のタスクをフォアグラウンドに持ってくることができるし、bg %5を使うと、停止中の番号5のコマンドをバックグラウンドで実行し続けさせることができるよ。
viコマンドなんかは、バックグラウンドに置く前に自動的に停止しちゃうから、忘れちゃわないようにファイルを保存してからバックグラウンドに置くのを忘れずにね。
6.4 プロセスを強制終了したり変更したりしよう
プロセスにいろんなシグナルを送ってその挙動を変えることもできるし、プロセスのプロセッサ優先度を変更することもできるんだ。
6.4.1 killとkillallコマンドでプロセスを強制終了させよう
この2つのコマンドは、よく実行中のプロセスを終了させるのに使われるけど、実際にはプロセスに有効なシグナルを送ってるんだ。シグナルは数字か名前で表されるよ。
| シグナル | 数字 | 説明 |
|---|---|---|
| SIGHUP | 1 | 設定ファイルを再読み込みする |
| SIGINT | 2 | キーボードからの割り込み |
| SIGQUIT | 3 | キーボードからの終了 |
| SIGABRT | 6 | abort(3)呼び出しで生成される中断シグナル |
| SIGKILL | 9 | 強制終了シグナル |
| SIGTERM | 15 | 終了シグナル |
| SIGCONT | 19, 18, 25 | 停止中のプロセスを再開する |
| SIGSTOP | 17, 19, 23 | プロセスを停止する |
最後の2つのシグナルについては、最初の値はAlphaとSPARC向け、真ん中の値はx86向け、最後の値はMIPSアーキテクチャ向けだよ。
デフォルトはSIGTERM (15) シグナルなんだ。異なるプロセスはいろんなシグナルに応答できるけど、SIGKILL (9) とSIGSTOPシグナルだけは、どんなプロセスもブロックできないんだよ。
- killコマンドを使ってPIDに基づいてプロセスにシグナルを送る
| |
例えば、プロセスIDが2333のプロセスを強制終了するなら:kill -9 2333とかkill -SIGKILL 2333って感じ。
- killallコマンドを使って名前に基づいてプロセスにシグナルを送る
killコマンドと似てるけど、同じ名前のコマンドをたくさん強制終了したいときにすごく便利なんだ。でも、うっかり大事な同じ名前のプロセスを変えちゃわないように注意してね。
例えば、gnome-shellを再起動するなら:killall -1 gnome-shellってやるよ。
6.4.2 niceとreniceコマンドでプロセッサの優先度を設定しよう
Linuxカーネルがどの実行中プロセスがCPUにアクセスできるかを決めるときに考慮する要素の一つが、プロセスについてるnice値なんだ。範囲は-20から19までで、デフォルトは0だよ。
nice値が低いほど優先度が高くなるんだ。rootユーザーだけが負の値を設定して優先度を上げられる(値を低くする)けど、一般ユーザーは優先度を下げることしかできない(値を高くする)んだよ。
niceコマンドを使って特定のnice値でコマンドを実行できるし、reniceコマンドとPIDを使ってすでに実行中のプロセスのnice値を変更することもできるんだ。例えばこんな感じ。
nice -n +5 updatedb &ってやると、updatedbコマンドをバックグラウンドで優先度5で実行するよ。
renice -n 3 2333ってやると、PIDが2333のプロセスのnice値を3に変更するんだ。
6.5 cgroupsを使ってプロセスを制限しよう
あるプロセスに設定したnice値は子プロセスには適用されないんだ。つまり、niceでは特定のユーザーやアプリケーションが使えるLinuxシステムの総リソース量を制限することはできないってこと。
cgroupsコマンドを使うと、プロセスをタスクとして特定して、特定のコントロールグループに所属させることができるんだ。タスクは階層構造で設定できて、その中にはデーモン(すべてのバックグラウンドサーバープロセスにデフォルトの制限が設定されてる)と呼ばれるタスクや、httpdやvsftpdなんかに対する特定の制限を設定するサブタスクが含まれるよ。
あるタスクがプロセスを起動すると、その子プロセスは親プロセスの制限設定を継承するんだ。制限内容は、ストレージ、プロセッサスケジューリング、プロセスレポート、CPU割り当て、デバイスアクセス、メモリ使用状況なんかが含まれるよ。
cgroupsの設定はかなり厄介かもしれないな。設定ファイルを編集してcgroupsを作成したり(/etc/cgconfig.conf)、特定のユーザーやグループを制限したり(/etc/cgrules.conf)するんだ。cgscreateコマンドを使ってcgroupsを作成し、それらのグループを/sys/fs/cgroup階層に追加することもできるよ。もし設定を間違えると、システムが起動できなくなる可能性もあるから注意してね。