Linuxシステムのプロセスを管理する基本コマンド
プロセスはどれも、システムのCPU時間やメモリ空間やディスク空間などのシステムリソースを使用している。しかしプロセスに問題が起こると、CPU時間やメモリ空間の過剰な消費が始まってしまい、その結果、他のプロセスが実行に必要なリソースを得ることができなくなってしまうことがある。
そのような暴走プロセスを管理するための方法を知っておくことは、Linuxのシステム管理では不可欠な知識だ。Linux上でプロセスを管理するためには、ps、top、service、kill、killallのようなコマンドラインツールを利用することができる。
ps
psは、マシン上で現在実行中のプロセスを表示する。psには数多くのオプションがあるが、中でももっとも便利な起動方法の一つとして、「ps aux
」がある。「ps aux
」と実行すると、システム上のすべてのプロセスが表示される。
ブート後の通常のLinuxサーバにはおそらく100個程度のプロセスがあるため、psコマンドの出力はかなり長いものになる。以下に、CentOS 5搭載のテスト用マシンで実行したpsの出力結果の最初の部分を示す。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 10308 668 ? S 15:03 0:00 init [5] root 2 0.0 0.0 0 0 ? S 15:03 0:00 [migration/0] root 3 0.0 0.0 0 0 ? SN 15:03 0:00 [ksoftirqd/0] root 4 0.0 0.0 0 0 ? S 15:03 0:00 [watchdog/0] root 5 0.0 0.0 0 0 ? S
各項目について以下に簡単に説明する。
- USER:プロセスを所有しているユーザのユーザ名。
- PID(プロセスID):各プロセスに与えられている一意のプロセス番号。
- %CPU:各プロセスのCPUの使用率。CPUを使用した時間をプロセスの実行時間で割った結果のパーセンテージで表示される。
- %MEM:プロセスが使用している物理メモリ量。
- VSZ:プロセスの仮想メモリサイズ(単位はキロバイト)。
- RSS:VSZと似ているが仮想メモリサイズではなく、プロセスが使用しているスワップされていない物理メモリ量(単位はキロバイト)。
- TTY:制御端末。
- STAT:プロセスの状態。なお
S
はプロセスがスリープ状態にあり、かつ、すぐにでも実行可能状態になる可能性があることを示し、N
はプロセスの優先度が低いことを示し、<
はプロセスの優先度が高いことを示す。その他に注目すべき文字には、l
(プロセスがマルチスレッド化されていることを示す)やR
(プロセスが実行中であることを示す)などがある。 - START:プロセスを起動した時刻。
- TIME:累積したCPU時間。プロセスが使用した全CPU時間と、そのプロセスのためにカーネルが使用した全CPU時間の合計。
より詳しい説明についてはpsのmanページを参照して欲しい。
psの長い出力結果から特定のプロセスを探すのは困難なこともある。そのような場合には、grepコマンドを利用してマッチする文字列を見つけ出すと良い。例えばsendmailのプロセスを見つけるためには以下のようなコマンドを使用する。
ps aux | grep sendmail root 2401 0.0 0.4 66444 2064 ? Ss 15:04 0:00 sendmail: accepting connections smmsp 2409 0.0 0.3 53040 1752 ? Ss 15:04 0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmqueue gary 3807 0.0 0.1 60224 700 pts/2 R+ 15:17 0:00 grep sendmail
上記のように実行すると、目的の文字列(sendmail)にマッチするためにgrepコマンド自体(上記の例ではPID 3807のプロセス)も出力に含まれる。しかし当然ながらそれはsendmailサービスの一部ではない。
top
psが特定の時点におけるシステム上のプロセスのスナップショットを示すのに対し、topプログラムはシステムの状況をリアルタイムで動的に表示する。topは、システムの概要(CPUやメモリの使用状況などの統計情報)と、稼働中のシステムで動的に変化する実行中のプロセス一覧とを表示する。なお出力結果では、CPUの使用率が最も高いプロセスから順に表示される。
以下にtopの実行結果の最初の部分を示す。
15:18:00 up 54 min, 0 users, load average: 0.00, 0.10, 0.11 Tasks: 115 total, 2 running, 113 sleeping, 0 stopped, 0 zombie Cpu(s): 0.7%us, 0.0%sy, 0.0%ni, 99.0%id, 0.3%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 467888k total, 458476k used, 9412k free, 15264k buffers Swap: 3204884k total, 0k used, 3204884k free, 222108k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 554 root 15 0 229m 9940 4548 S 0.7 2.1 0:10.29 Xorg 1 root 15 0 10308 668 552 S 0.0 0.1 0:00.11 init 2 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.01 ksoftirqd/0
上記の出力結果の後半部分はpsコマンドの出力とほぼ同じ内容だ。前半部分のSwap: から始まる行は、スワップ領域の使用状況を把握する際に役立つ。topについてさらに詳しくはtopのmanページを参照して欲しい。
service
sendmailやApacheウェブサーバのようなサービスをコマンドラインから起動/停止するための最も簡単な方法は、serviceコマンドを使用することだ。各サービスにはそのサービスを簡単に起動/停止するためのスクリプトが用意されていて、serviceコマンド経由で利用することができる。
サービスの状態を確認するためには、例えばsendmailの場合、「service sendmail status
」と実行する。実行結果は以下のようなものになるはずだ。
sendmail (pid 4660 4652) is running...
実行中のsendmailを停止するには、「service sendmail stop
」と実行する。そして再び起動するには「service sendmail start
」とする。なお停止と再起動を一度で行なうには「service sendmail restart
」と実行すればよい。
けれどもserviceコマンドを使用しても暴走中のサービスを停止することができない場合もある。そのような場合には、以下に紹介するkillコマンドとkillallコマンドを使用する必要がある。
killとkillall
killは、実行中のプロセスの停止を試みるコマンドだ。Linuxでは、オペレーティングシステムがプロセスに対して停止のシグナルを送ることによってプロセスが停止する。killのデフォルトのシグナルは、ソフトウェアの終了を指示するTERM(シグナル番号15)だ。プロセスはTERMシグナルを受け取ると、決められた方法できちんと停止することになっている。しかしプロセスが暴走していると、きちんと停止のシグナルが送られても反応しない可能性がある。そのような場合には、KILLシグナル(短く「シグナル9」とも呼ばれる)を送る必要がある。そこで実行中のプロセス(例えばPIDが1234のプロセス)を強制終了するためには「 kill -9 1234
」とする。
一方killallコマンドは、PIDではなく名前によって指定することで実行中のプロセスを停止する。これには直接的な利点が2点あり、まずプロセスを停止するためにpsコマンドを使ってPIDを探す必要がない。次に、同じ名前の複数のプロセスがある場合(Apacheウェブサーバの場合など)に、そのようなプロセスのすべてを一挙に停止することができる。killの場合と同様にkillallもシグナルをパラメータとして受け取り、プロセスの強制終了には-9
を使用する。したがって例えばApacheのプロセスをすべて強制終了したい場合には、「killall -9 httpd
」とする。
反応しなくなったウェブサーバの再起動
それでは以上のようなコマンドを実際的な問題の解決にどのように使用するのかという一例を見てみよう。ウェブサーバが反応しなくなり再起動が必要となっていることに気付いたら、まずはserviceコマンドを試してみよう。ウェブサーバの起動/停止用のスクリプトが実行され、ウェブサーバを再起動することができるはずだ。CentOS 5上のApacheの場合には以下のように実行する。
service httpd restart
上記が失敗したら次に、ウェブサーバのプロセスを強制終了させるために、killallコマンドを試してみよう。
killall -9 httpd
その後、psを実行してApacheのサービスがすべて終了したことを確かめよう。
ps aux | grep httpd
まだ終了しないプロセスが残っていた場合には、killコマンドを使用して一つ一つ強制終了させよう。最後に以下のようにしてウェブサーバを再開すればよい。
service httpd start
最近友人に、fetchmailプロセスに関する問題が起こったという。fetchmailは、外部のメールサーバからメールを取得してローカルのサーバに受け渡すためのプログラムだ。ある朝彼は自分のシステムが低速になっていることに気付いた。topコマンドで素早く確認したところ、fetchmailのプロセスがシステムメモリの99%を使用していたことが分かった。そこでfetchmailプロセスのPIDを調べて、fetchmailプロセスを終了させ、serviceコマンドを使用して再起動した。その結果メモリが解放されて、システムが生き返ったとのことだ。
まとめ
異常な動作をしているプロセスがないことを確実にするために、システムを監視するようにしよう。そのための簡単な方法の一つとして、端末ウィンドウでtopコマンドを常時実行しておくという方法がある。そうしておけば、すべてが順調に動いていることを時折素早く確認することができる。また実際に何かがおかしくなり始めた場合にも、Linuxにはプロセスを停止して再開させるための便利なツールがあるので、システム全体の再起動はまれにしか必要にはならないだろう。
Gary Simsはイギリスの大学でビジネス情報システムの学位を取得しており、ソフトウェアエンジニアとしての経験が10年ある。現在はフリーランスのLinuxライター/コンサルタント。