Linux & IT ノート

プロセスとジョブ管理:ps・top・kill・jobs

管理人 約9分で読めます

プロセスとは、OS 上で実行中のプログラムのことです。コマンドを叩いた瞬間、カーネルはそのプログラム用にメモリ空間を確保し、固有の識別番号(PID: Process ID)を割り当てます。Linux を使いこなすうえで、今どのプロセスが動いているかを確認し、必要に応じてコントロールする能力は欠かせません。本記事ではプロセスの確認・監視・終了から、ジョブとしてバックグラウンドで扱う方法まで一通り押さえます。

プロセスを確認する:ps

ps(process status)はスナップショット形式でプロセス一覧を表示するコマンドです。よく使うオプションは以下の2パターン。

# BSD スタイル: 全ユーザーの全プロセスを詳細表示
ps aux

# UNIX スタイル: 同様だが出力列が若干異なる
ps -ef

ps aux の出力例:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.1 168396 11000 ?        Ss   Jun18   0:02 /sbin/init
youhei    1234  0.3  1.2 512000 48000 pts/0    Sl   10:00   0:05 python3 server.py

主要列の意味:%CPU%MEM はそのまま CPU・メモリ使用率、VSZ は仮想メモリサイズ、RSS は実メモリ使用量(KB)、STAT はプロセスの状態(S = スリープ、R = 実行中、Z = ゾンビ)です。

特定のプロセスを探すときは grep と組み合わせます。

# nginx プロセスだけ絞り込む
ps aux | grep nginx

# PID が分かっている場合
ps -p 1234 -o pid,comm,%cpu,%mem

pgrep を使うとより簡潔です。

# プロセス名から PID を取得
pgrep nginx

# プロセス名とあわせて PID を表示(-l)
pgrep -l python3

リアルタイム監視:top / htop

ps はある瞬間のスナップショットですが、top はリアルタイムで更新し続けます。

top

起動するとヘッダ行に総プロセス数・CPU 使用率・メモリの概況が表示され、その下にプロセス一覧が並びます。デフォルトは CPU 使用率の降順です。

主要な操作キー:

キー動作
q終了
kPID を入力してシグナル送信
Mメモリ使用率順に並び替え
PCPU 使用率順に並び替え(デフォルト)
1CPU コアごとの使用率を展開表示
u特定ユーザーのプロセスに絞り込む

htop はカラー表示でマウス操作にも対応したより使いやすい代替ツールです。多くのディストリビューションで apt install htopdnf install htop で入ります。CPU コアごとの使用率バーが視覚的に分かりやすく、プロセスをカーソルで選択して F9 でシグナルを送れるため、サーバーの状況を把握するのに重宝します。

シグナルとプロセス終了:kill・killall・pkill

シグナルとは

シグナルはプロセスへの非同期通知で、OS がプロセスに「何かすべきこと」を伝える仕組みです。よく使うシグナルは2つ。

シグナル名番号意味
SIGTERM15終了要求(プロセスが受け取り、後処理してから終了できる)
SIGKILL9強制終了(カーネルが即座に強制終了、後処理不可)
# SIGTERM を送る(デフォルト、番号省略可)
kill 1234
kill -15 1234
kill -SIGTERM 1234

# SIGKILL を送る
kill -9 1234

kill -9 は最終手段です。SIGKILL を受けたプロセスはファイルの書き込みバッファをフラッシュする間もなく終了するため、データ破損やロックファイルの残留が起きることがあります。まず kill(SIGTERM)を試み、数秒待っても終了しない場合に限り -9 を使うのが原則です。

プロセス名で指定したい場合は killallpkill が便利です。

# プロセス名で全インスタンスに SIGTERM
killall nginx

# 正規表現で一致するプロセスに送る
pkill -f "python3 server"

# ユーザーを絞って kill
pkill -u youhei python3

pkillpgrep と対になるコマンドで、シグナルを送る前に pgrep -l <パターン> でどのプロセスがマッチするか確認しておく習慣をつけると安全です。

ジョブ管理:フォアグラウンドとバックグラウンド

バックグラウンド実行と jobs

コマンド末尾に & を付けると、シェルを占有せずバックグラウンドで実行されます。

# バックグラウンドで起動
python3 -m http.server 8080 &
# [1] 5678  ← ジョブ番号と PID が表示される

起動中のジョブは jobs で確認できます。

jobs
# [1]+  Running    python3 -m http.server 8080 &

Ctrl+Z・fg・bg

実行中のコマンドを一時停止してシェルを取り戻したいときは Ctrl+Z を押します。プロセスは停止状態(STOPPED)になり、ジョブリストに追加されます。

# 実行中に Ctrl+Z を押すと
# [1]+  Stopped    python3 -m http.server 8080

# バックグラウンドで再開
bg %1

# フォアグラウンドに戻す
fg %1

%1 はジョブ番号の指定です。ジョブが1つだけなら % だけでも動きます。

nohup と disown

ターミナルを閉じると、そのシェルの子プロセス全体に SIGHUP(ハングアップシグナル)が送られてプロセスが終了します。セッションを超えてプロセスを生かし続けたい場合は nohupdisown を使います。

# nohup で起動(stdout は nohup.out に書き出される)
nohup python3 server.py &

# すでに起動済みのジョブをシェルから切り離す
jobs         # ジョブ番号を確認
disown %1    # ジョブ番号 1 を切り離す

長時間動かすスクリプトには tmuxscreen のほうが管理しやすいですが、nohup &disown は追加ツール不要ですぐ使えるので知っておくと便利です。

実践的なコツと落とし穴

ゾンビプロセスは終了したのに親プロセスが wait() を呼び出していないために残ったプロセスです。ps aux の STAT 列に Z が表示されます。ゾンビ自体はリソースをほぼ消費しませんが、PID テーブルを占有します。親プロセスを再起動するか終了させると、ゾンビは init(PID 1)に引き取られ自動的に回収されます。大量のゾンビが発生しているなら、それはそのアプリケーションのバグのサインです。

親子関係も重要です。ps -efPPID(Parent PID)列を見ると、プロセスの親子関係が分かります。親プロセスを kill すると子プロセスも連鎖終了するケースがありますが、子が SIGTERM を無視して残ることもあるため、重要なデーモンを停止するときは systemctl stop 経由で行うほうが確実です。

pgrep は grep より誤爆が少なく、UID やセッションでの絞り込みにも対応しているため、ps aux | grep の代わりに積極的に使うことをおすすめします。特に pkill の前の事前確認として pgrep -la <パターン> を挟む癖をつけると、意図せず関係ないプロセスを終了させるミスを防げます。

まとめ

プロセス管理の全体像が頭に入ると、Linux の操作に対する不安が一段と薄れます。最初は数も多く仕組みも入り組んで見えますが、使うコマンドは絞られていて、慣れると手足のように扱えるようになります。

  • ps aux でスナップショット確認、top/htop でリアルタイム監視
  • シグナルはまず SIGTERM、応答しないときだけ SIGKILL
  • & でバックグラウンド起動、Ctrl+Z + bg で後から切り替え
  • セッションを超えて動かすには nohupdisown
  • プロセス操作の前に pgrep -l で対象を確認する習慣が大切

これらを組み合わせて使えるようになると、システムの今の状態を自分で読み解けるという感覚が生まれてきます。

次回(#5)は パッケージ管理を扱います。aptdnfpacman の基本と、依存関係の仕組みを整理します。