LPIC Level1 復習ラジオ 14:プロセス管理
音声
目次
プロセスとは
プロセスは、実行中のプログラムです。ディスク上に保存されているプログラムを実行すると、カーネルがメモリやCPU時間などを管理するプロセスとして扱います。
同じプログラムから、複数のプロセスが起動することもあります。
sleep 300 &
sleep 300 &
ps -C sleep
この例では、同じsleepプログラムから二つのプロセスが起動し、それぞれ異なるPIDを持ちます。
| 用語 | 意味 |
|---|---|
| プログラム | ディスクなどに保存された実行可能な命令やデータ |
| プロセス | 実行中のプログラムをカーネルが管理する単位 |
| スレッド | プロセス内で実行される処理の流れ |
| デーモン | 通常はバックグラウンドで継続的に動作するサービス用プロセス |
| ジョブ | 対話型シェルがまとめて管理するコマンドやパイプライン |
プロセスとジョブは同じではありません。一つのジョブがパイプラインを含み、複数のプロセスで構成される場合があります。
grep ERROR access.log | less
このパイプラインは、シェルから見ると一つのジョブですが、通常はgrepとlessという複数のプロセスを含みます。
PID・PPID・プロセス状態
PIDとPPID
各プロセスには、プロセスIDであるPIDが割り当てられます。PPIDは、そのプロセスを起動した親プロセスのPIDです。
echo $$
ps -o pid,ppid,stat,cmd -p $$
$$は、現在のシェルのPIDへ展開されます。
| 項目 | 意味 |
|---|---|
PID | プロセスを識別する番号 |
PPID | 親プロセスのPID |
UID・USER | プロセスを所有する利用者 |
TTY | 関連付けられた端末 |
STAT | プロセス状態と追加属性 |
CMD・COMMAND | 実行中のコマンド |
主なプロセス状態
| 状態 | 意味 |
|---|---|
R | 実行中、またはCPUで実行されるのを待っている |
S | 割り込み可能なスリープ。イベントを待っている |
D | 割り込み不可能なスリープ。主にI/O待ちなど |
T | 停止中、またはトレース中 |
Z | ゾンビ。終了済みだが親が終了状態を回収していない |
I | アイドル状態のカーネルスレッド |
STATには、状態を示す先頭文字に加えて、追加属性が表示されることがあります。
| 追加記号 | 主な意味 |
|---|---|
< | 高い優先度 |
N | 低い優先度、つまりnice値が正 |
s | セッションリーダー |
l | マルチスレッド |
+ | フォアグラウンドのプロセスグループに属する |
ゾンビプロセス
ゾンビは、すでに実行を終了しています。そのため、ゾンビ自身へSIGKILLを送って通常のプロセスのように終了させることはできません。
ps -eo pid,ppid,stat,cmd | grep '[Z]'
ゾンビが残る場合は、PPIDを確認し、親プロセスが子の終了状態を回収していない原因を調べます。親プロセスを無条件に終了するのではなく、サービスへの影響を確認します。
psの基本
psは、選択したプロセスの情報を、その時点のスナップショットとして表示します。
ps [オプション]
Linuxで一般的なprocps-ng版のpsは、主に三種類のオプション形式を受け付けます。
| 形式 | 例 | 特徴 |
|---|---|---|
| UNIX形式 | ps -ef | オプションの前にハイフンを付ける |
| BSD形式 | ps aux | 通常はハイフンを付けない |
| GNU長形式 | ps --forest | 二つのハイフンと長い名前を使う |
形式を混ぜると、選択範囲や既定の表示内容が変わることがあります。まずは、よく使う形をまとまりとして覚えます。
現在の端末に関係するプロセスを表示する
ps
オプションなしでは、通常、現在の利用者と端末に関連する一部のプロセスが表示されます。
全プロセスを詳細表示する
ps -ef
-eは全プロセス、-fは完全形式の表示です。UID、PID、PPID、開始時刻、コマンドなどを確認できます。
BSD形式で全体を表示する
ps aux
aは端末を持つ他利用者のプロセスも含め、xは端末を持たないプロセスも含めます。uは利用者指向の表示形式です。
ps auxのauxには、通常ハイフンを付けません。
階層を表示する
ps -ef --forest
ps axf
親子関係を木構造に近い形で確認できます。
特定PIDを表示する
ps -p 1234
ps -fp 1234
-pはPIDで対象を選択します。
psの絞り込み・表示形式・並べ替え
利用者で絞り込む
ps -u alice
ps -U alice
procps-ng版では、-uは実効ユーザーID、-Uは実ユーザーIDによる選択です。一般的な確認では、所有者名でps -u 利用者名を使うことが多くあります。
コマンド名で絞り込む
ps -C sshd
ps -C nginx -o pid,ppid,user,stat,cmd
-Cは、実行可能ファイル名によって対象を選択します。
親PIDで絞り込む
ps --ppid 1234
ps -o pid,ppid,stat,cmd --ppid 1234
指定した親プロセスの子プロセスを確認できます。
表示項目を指定する
ps -eo pid,ppid,user,stat,ni,%cpu,%mem,cmd
ps -p 1234 -o pid,etimes,stat,ni,cmd
-oは、表示する列を指定します。-eと組み合わせると、全プロセスについて必要な列だけを表示できます。
| 列名 | 意味 |
|---|---|
pid | PID |
ppid | PPID |
user | 所有者名 |
stat | プロセス状態 |
ni | nice値 |
%cpu | CPU使用率に関する値 |
%mem | 物理メモリに対する使用率 |
etime・etimes | 起動後の経過時間 |
cmd・args | 引数を含むコマンドライン |
並べ替える
ps -eo pid,user,%cpu,%mem,stat,cmd --sort=-%cpu
ps -eo pid,user,%mem,%cpu,stat,cmd --sort=-%mem
ps -eo pid,ppid,cmd --sort=ppid,pid
--sortでは、列名の前のマイナスが降順、プラスまたは記号なしが昇順です。
grepと組み合わせる場合
ps -ef | grep '[s]shd'
grep sshdでは、検索中のgrep自身も結果に含まれる場合があります。角括弧を使う方法のほか、利用できる環境ではpgrepやps -Cも選択肢です。
スナップショットであることを意識する
psは実行した時点の情報です。継続的に変化を見る場合はtopを使います。
top
topは、システムの概要とプロセス一覧を動的に更新して表示します。
top
上部の概要
表示内容は設定やバージョンで変わりますが、一般的には次の情報を確認できます。
- 現在時刻、稼働時間、ログイン利用者数
- ロードアベレージ
- プロセスやスレッドの状態別件数
- CPU時間の内訳
- 物理メモリとスワップの使用状況
ロードアベレージは、単純なCPU使用率ではありません。実行可能状態や割り込み不可能な待ち状態にある処理数の平均を示す指標として扱います。
主なプロセス列
| 列 | 意味 |
|---|---|
PID | プロセスID |
USER | 所有者 |
PR | スケジューリング優先度 |
NI | nice値 |
VIRT | 仮想メモリの総量 |
RES | 物理メモリ上に常駐している量 |
SHR | 共有可能なメモリ量 |
S | プロセス状態 |
%CPU | CPU使用状況 |
%MEM | 物理メモリに対する使用率 |
TIME+ | 使用したCPU時間の累計 |
COMMAND | コマンド名またはコマンドライン |
主な対話キー
| キー | 主な操作 |
|---|---|
P | CPU使用状況を基準に並べ替える |
M | メモリ使用状況を基準に並べ替える |
T | CPU時間を基準に並べ替える |
k | PIDとシグナルを指定してシグナルを送る |
r | 指定プロセスのnice値を変更する |
dまたはs | 更新間隔を変更する |
1 | CPUごとの表示を切り替える |
H | スレッド表示を切り替える |
hまたは? | ヘルプを表示する |
q | 終了する |
バッチモード
top -b -n 1
top -b -n 1 -o %MEM | head -n 20
top -p 1234
-b:端末操作を前提としないバッチモード-n 1:一回更新した後に終了する-p PID:指定PIDを監視する
スクリプトやログ取得では、対話画面ではなくバッチモードを使います。
シグナルとkill
シグナルは、プロセスへイベントを通知する仕組みです。killという名前でも、必ずしも強制終了だけを行うコマンドではありません。
kill [シグナル指定] PID...
利用できるシグナルを確認する
kill -l
kill -l 15
シグナルは、名前または番号で指定できます。移植性や可読性を考えると、スクリプトでは名前による指定が分かりやすい場合があります。
| シグナル | Linuxで一般的な番号 | 主な意味 |
|---|---|---|
SIGHUP | 1 | 端末切断の通知。デーモンが設定再読み込みに利用する場合もある |
SIGINT | 2 | 端末からの割り込み。通常はCtrl+Cで送られる |
SIGKILL | 9 | 強制終了。捕捉、無視、ブロックできない |
SIGTERM | 15 | 終了要求。killの既定シグナル |
SIGCONT | 18 | 停止中のプロセスを再開する |
SIGSTOP | 19 | 強制停止。捕捉、無視、ブロックできない |
SIGTSTP | 20 | 端末からの停止要求。通常はCtrl+Zで送られる |
シグナル番号はアーキテクチャによって異なる場合があります。試験で頻出する1、2、9、15などを押さえつつ、実機ではkill -lで確認します。
通常の終了要求
kill 1234
kill -TERM 1234
kill -15 1234
シグナルを省略するとSIGTERMです。対象プロセスは終了処理を実装していれば、ファイルを閉じる、状態を保存するなどの後始末を行えます。
強制終了
kill -KILL 1234
kill -9 1234
SIGKILLはプロセス側で処理できず、後始末の機会を与えません。最初からkill -9を使うのではなく、通常はSIGTERMで終了を依頼し、応答しない場合に限って検討します。
停止と再開
kill -STOP 1234
kill -CONT 1234
SIGSTOPは実行を停止し、SIGCONTは再開します。停止は終了ではありません。
設定再読み込み
kill -HUP 1234
SIGHUPの扱いはプログラムごとに異なります。設定再読み込みとして利用するデーモンもありますが、必ず公式ドキュメントやサービスのmanページを確認します。
シグナル0による確認
kill -0 1234
echo $?
シグナル0では実際のシグナルを送らず、PIDの存在や送信権限を確認できます。ただし、終了直後にPIDが別プロセスへ再利用される可能性もあるため、PIDだけで長時間後の同一性を保証できるとは考えません。
killall
killallは、指定したコマンド名で動作するプロセス群へシグナルを送ります。Linuxで一般的なpsmisc版では、シグナルを省略するとSIGTERMです。
killall [オプション] コマンド名...
コマンド名で終了を依頼する
killall sleep
killall -TERM sleep
同じ名前で動いている複数のプロセスが対象になる可能性があります。実行前にps -Cなどで対象を確認します。
強制終了する
killall -KILL sleep
killと同様、SIGKILLは最後の手段として扱います。
確認しながら実行する
killall -i sleep
-iは、各プロセスへシグナルを送る前に確認します。
利用者を指定する
killall -u alice sleep
-uは、指定利用者が所有する対象に絞り込みます。
終了を待つ
killall -w sleep
-wは、対象プロセスが終了するまで待ちます。対象がシグナルを無視する、ゾンビになる、PIDが再利用されるなどの状況では、待ち続ける可能性があるため注意します。
jobs・bg・fg
jobs、bg、fgは、現在の対話型シェルが管理しているジョブを操作するBashの組み込みコマンドです。
フォアグラウンドとバックグラウンド
フォアグラウンドジョブは端末の前面で動作し、通常はキーボード入力を受け取ります。バックグラウンドジョブは、シェルのプロンプトを利用できる状態で動作します。
sleep 300 &
行末の&を付けると、コマンドをバックグラウンドで開始します。
実行中のジョブを停止する
sleep 300
# 実行中に Ctrl+Z
通常、Ctrl+ZはフォアグラウンドジョブへSIGTSTPを送り、ジョブを停止状態にします。終了ではありません。
ジョブ一覧を表示する
jobs
jobs -l
jobsは、現在のシェルが管理するジョブ番号と状態を表示します。-lを付けると、PIDも表示します。
[1]- Running sleep 300 &
[2]+ Stopped less large.log
[1]や[2]がジョブ番号です。プラス記号は現在のジョブ、マイナス記号はその一つ前のジョブを表します。
バックグラウンドで再開する
bg %2
bgは、停止中のジョブをバックグラウンドで再開します。
フォアグラウンドへ戻す
fg %1
fg %2
fgは、指定ジョブをフォアグラウンドへ移動します。
ジョブ指定
| 指定 | 意味 |
|---|---|
%1 | ジョブ番号1 |
%+または%% | 現在のジョブ |
%- | 一つ前のジョブ |
%文字列 | その文字列で始まるコマンドのジョブ |
%?文字列 | その文字列を含むコマンドのジョブ |
ジョブへシグナルを送る
kill %1
kill -STOP %1
kill -CONT %1
Bash組み込みのkillでは、PIDだけでなくジョブ指定を使えます。
ジョブ番号とPIDの違い
| 識別子 | 管理範囲 | 主な確認方法 |
|---|---|---|
| ジョブ番号 | 現在のシェル内 | jobs |
| PID | OSが管理するプロセス | ps、top |
別の端末や別のシェルで開始した処理は、現在のシェルのjobsには通常表示されません。その場合はPIDを調べて管理します。
また、バックグラウンド化しても、標準出力や標準エラー出力は端末へ表示される場合があります。必要に応じて、開始時にリダイレクトします。
long_command > output.log 2>&1 &
nice・renice
nice値は、通常のタイムシェアリング対象プロセスについて、CPUスケジューリング上の扱われやすさに影響する値です。
Linuxでは一般に、nice値は-20から19の範囲です。
| nice値 | 意味 |
|---|---|
-20に近い | プロセスにとって有利。高い優先度 |
0 | 一般的な初期値 |
19に近い | プロセスにとって不利。低い優先度 |
数字が小さいほど優先度が高く、数字が大きいほど優先度が低い点に注意します。「niceなプロセスほど他の処理へCPUを譲る」と覚えると整理しやすくなります。
niceで新しいコマンドを起動する
nice -n 10 long_command
nice -n 15 tar -czf backup.tar.gz large_directory/
GNU niceの-nは、現在のnice値へ指定値を加えた状態でコマンドを実行します。指定しない場合の調整値は10です。
nice long_command
多くの場合、通常利用者はnice値を増やして優先度を下げられます。nice値を減らして優先度を上げる操作には、通常は追加の権限が必要です。
現在のnice値を確認する
nice
ps -o pid,ni,stat,cmd -p 1234
top -p 1234
引数なしのGNU niceは、現在のnicenessを表示します。個別プロセスはpsのNI列やtopで確認します。
reniceで実行中プロセスを変更する
renice 10 -p 1234
renice --priority 15 -p 1234
util-linux版のreniceでは、通常、指定値を新しい絶対nice値として扱います。
利用者やプロセスグループを対象にする
renice 10 -u alice
renice 5 -g 4321
-p:PIDを指定する-u:利用者を指定する-g:プロセスグループIDを指定する
niceとreniceの違い
| コマンド | 対象 | 代表例 |
|---|---|---|
nice | これから起動するコマンド | nice -n 10 command |
renice | すでに動いているプロセスなど | renice 10 -p PID |
nice値はCPUスケジューリングへのヒントであり、メモリ使用量、ディスクI/O、ネットワーク帯域を直接制限する値ではありません。また、リアルタイムスケジューリングなど、別の方針には別の仕組みがあります。
確認から終了までの実践手順
1. 対象を特定する
ps -C program_name -o pid,ppid,user,stat,ni,%cpu,%mem,cmd
ps -eo pid,ppid,user,stat,ni,%cpu,%mem,cmd --sort=-%cpu
top
名前だけで判断せず、PID、所有者、親プロセス、状態、コマンドラインを確認します。
2. サービス管理対象かを確認する
systemdで管理されているサービスなら、個別プロセスを直接終了するより、サービス単位で操作する方が適切な場合があります。
systemctl status service_name
systemctl stop service_name
自動再起動が設定されたサービスでは、個別PIDへkillしても再び起動する場合があります。
3. 通常の終了要求を送る
kill -TERM 1234
まずはSIGTERMで、後始末を行える形の終了を依頼します。
4. 終了したか確認する
ps -p 1234
kill -0 1234
echo $?
対象が消えたか、状態が変化したか、別のPIDで再起動していないかを確認します。
5. 応答しない原因を確認する
ps -o pid,ppid,stat,wchan:24,cmd -p 1234
D状態などでは、プロセスがカーネル内のI/O待ちから戻るまで、シグナルによる終了が直ちに反映されない場合があります。単純にシグナルを繰り返すのではなく、ストレージやネットワークファイルシステムなどの待ち原因も確認します。
6. 最後の手段として強制終了する
kill -KILL 1234
影響を理解した上で、通常終了できない場合に限って使用します。
よくある間違い
| 間違いやすい点 | 確認すること |
|---|---|
最初からkill -9を使う |
まずSIGTERMで終了を依頼し、後始末の機会を与える |
killは終了専用だと思う |
停止、再開、再読み込みなど、各種シグナルを送るコマンド |
ps auxをps -auxと覚える |
BSD形式の代表例はハイフンなしのps aux |
jobsで全システムのプロセスを探す |
jobsは現在のシェルが管理するジョブだけ |
Ctrl+Zで終了したと思う |
Ctrl+Zは通常停止。jobsで状態を確認する |
| nice値が大きいほど優先度が高いと思う | nice値は小さいほど高優先度、大きいほど低優先度 |
niceとreniceを混同する |
niceは新規起動、reniceは実行中の対象 |
ゾンビへkill -9を繰り返す |
ゾンビは終了済み。PPIDを確認し、親側の回収処理を調べる |
killallを対象確認なしで使う |
同名プロセスを複数対象にする可能性があるため、先に一覧を確認する |
| サービスの子プロセスだけを終了する | systemd管理対象なら、サービス単位の停止や再起動を検討する |
manページとヘルプを確認する
man ps
man top
man kill
man killall
help jobs
help bg
help fg
help kill
man nice
man renice
man 7 signal
30秒チェック
- PIDとPPIDは、それぞれ何を表すでしょうか。
psとtopは、表示の性質がどのように違うでしょうか。- 全プロセスを完全形式で表示する代表的な
psコマンドは何でしょうか。 ps auxのauxには、通常ハイフンを付けるでしょうか。killでシグナルを省略したとき、何が送られるでしょうか。SIGTERMとSIGKILLの重要な違いは何でしょうか。jobsで表示されるジョブ番号とPIDは、管理範囲がどう違うでしょうか。Ctrl+Z、bg、fgは、それぞれ何をするでしょうか。- nice値は、小さい値と大きい値のどちらが高い優先度でしょうか。
niceとreniceの対象は、どう違うでしょうか。
答えを表示
- PIDはプロセス自身の識別番号、PPIDは親プロセスのPID
psは実行時点のスナップショット、topは動的に更新する表示ps -ef- 付けない。代表的なBSD形式は
ps aux SIGTERMSIGTERMはプロセスが処理して後始末できるが、SIGKILLは捕捉や無視ができず、後始末の機会を与えない- ジョブ番号は現在のシェル内、PIDはOSが管理するプロセスの識別番号
Ctrl+Zは通常ジョブを停止し、bgはバックグラウンドで再開、fgはフォアグラウンドへ移動する- 小さい値。
-20に近いほど高く、19に近いほど低い niceはこれから起動するコマンド、reniceは実行中のプロセスなど
要約
- プロセスは実行中のプログラムで、PIDにより識別され、PPIDで親プロセスを確認できます。
Rは実行可能、Sは割り込み可能なスリープ、Dは割り込み不可能な待ち、Tは停止、Zはゾンビです。psは実行時点のスナップショット、topは動的に更新される一覧です。ps -efとps auxは全体確認の代表例で、ps auxは通常ハイフンなしです。ps -oで列を指定し、--sort=-%cpuなどで並べ替えられます。killはPIDへシグナルを送り、省略時はSIGTERMです。SIGKILLは捕捉、無視、ブロックができず、後始末の機会を与えないため最後の手段です。killallはコマンド名で複数プロセスを対象にできるため、事前確認が重要です。jobs、bg、fgは、現在のシェルが管理するジョブを操作します。Ctrl+Zは通常停止であり、終了ではありません。- nice値は
-20に近いほど高優先度、19に近いほど低優先度です。 niceは新しく起動するコマンド、reniceは実行中のプロセスなどのnice値を変更します。
参考資料
- ps(1) — Linux manual page
- top(1) — Linux manual page
- kill(1) — Linux manual page
- killall(1) — Linux manual page
- signal(7) — Linux manual page
- proc_pid_stat(5) — Linux manual page
- GNU Bash Manual:Job Control Basics
- GNU Bash Manual:Job Control Builtins
- GNU Coreutils:nice invocation
- nice(1) — Linux manual page
- renice(1) — Linux manual page
- procps-ng Project