Linuxのプロセスとは|ps/topによる確認・親子関係・状態(S/R/D/Z)・kill/シグナルの基本

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)【Linux入門】初心者のための基礎知識・講座 > Linuxのプロセスとは|ps/topによる確認・親子関係・状態(S/R/D/Z)・kill/シグナルの基本
「Linuxサーバーが重いんだけど、どのプロセスがCPUを食っているのか調べたい」
「そもそもプロセスって何?スレッドやジョブと何が違うの?」

プロセスはLinuxを理解するうえで避けて通れない基本概念です。ps・top・systemdなど現場で使うコマンドの大半は、プロセスを起点に動作しています。

この記事では、Linuxにおけるプロセスの基本的な考え方から、ps・topによる確認方法、親子関係、状態(State)の読み方、プロセスとスレッドの違い、シグナルによる制御まで、現役のサーバー管理者の視点で解説します。

この記事のポイント

・Linuxのプロセスとは「実行中のプログラム」のことで、PIDで一意に管理される
・現在のプロセス一覧は ps aux または top で確認できる
・親子関係(PPID)を持ち、initまたはsystemd(PID 1)が全プロセスの祖先
・状態(S/R/D/Z)を読めると重さやハング原因の切り分けができる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
図解60P/登録10秒/解除も3秒 / 詳細はこちら

Linuxプロセスとは何か

プロセスは、タスクともよばれるLinux上で動作中のプログラムのことを指します。

例えば、あなたがシェルから実行したプログラムは、実行中はプロセスとしてLinux上で扱われ管理されます。同じプログラムを続けて実行しても、プロセス上は別のものとして扱われます。

プロセスにはそれぞれ一意の番号(PID:Process ID)が割り振られていて、LinuxカーネルはこのPIDをもとにプロセスを管理しています。1つのプログラムを2回起動すれば、PIDが異なる2つのプロセスとして並行して走ります。

実際に、現在起動しているプロセスを確認するには ps コマンドを実行してみるといいでしょう。下のように ps ax と入力してみてください。

# 現在実行中のプロセスをすべて表示 [user@web01 ~]$ ps ax PID TTY STAT TIME COMMAND 1 ? Ss 0:04 /usr/lib/systemd/systemd --switched-root --system --deserialize 22 2 ? S 0:00 [kthreadd] 3 ? I< 0:00 [rcu_gp] 4 ? I< 0:00 [rcu_par_gp] 10 ? I< 0:00 [mm_percpu_wq] 11 ? S 0:00 [ksoftirqd/0] 12 ? I 0:08 [rcu_sched] 13 ? S 0:00 [migration/0] 388 ? S 0:00 /usr/sbin/chronyd -F 2 440 ? Ss 0:00 /usr/lib/systemd/systemd-journald 450 ? S 0:00 /usr/lib/systemd/systemd-logind 1234 ? Ss 0:00 /usr/sbin/sshd -D 2345 pts/0 Ss 0:00 -bash 3456 pts/0 R+ 0:00 ps ax

「ps ax」と入力すると、現在サーバー上で起動しているプロセスをすべて表示できます。

あなたのLinuxも上と同じような表示がされたのではないでしょうか? これが、私たちが目に見ることができるプロセスです。

マルチタスクとプロセス管理の仕組み

よくマルチタスクという言葉を聞くと思いますが、これは複数のプロセス(プログラム)が実行されている状態のことをいいます。

ただし、これは正確な表現ではありません。厳密にはプログラムを複数実行させているように見せていると言った方が正しいです。

普通コンピュータのCPUは1コアにつき1つしかありません。1つのCPUコアが同時に処理できるプログラムも1つです。

では、どうやって複数のプログラムを処理しているかというと、コンピュータは時分割方式(Time Sharing System)という方式をつかって、複数のプログラムを高速に切り替えることにより同時に処理しているように見せているのです。

簡単にいうと、プログラムを時間単位で細かく区切って、少しずつCPUに割り当てて処理している、ということになります。

もっと分かりやすく例えると、今あなたが勉強しているとします。あなたがCPU、そして勉強教科がプロセスだとすると、数学を5分、科学を5分、社会を5分と勉強してまた数学を5分勉強するといったように、細かく時間を分割しながら勉強するといったことです。

コンピュータはこの動きを高速で行うため、まるで同時に処理させているかのようにみえるのです。そして、これがマルチタスクです。

プロセス管理という言葉がありますが、これはプロセス同士がCPUや、メモリを奪いあって混乱しないようにするための機能です。Linuxはこの機能が強力なため、ここまで堅牢で安定度の高い人気のあるサーバーOSになったといっても良いでしょう。

なお、最近のサーバーCPUはマルチコア・マルチスレッドが当たり前なので、4コア8スレッドのCPUなら理論上8つのプロセスを同時に実行できます。それでも、現代のLinuxサーバーでは常時数百~数千のプロセスが動いているのが普通なので、時分割によるスケジューリングは依然として中核機能です。

プロセスの親子関係(PPID)

Linuxのすべてのプロセスは「誰かに生み出された子」です。プロセスは親プロセス(Parent Process)から fork() システムコールで複製・派生して生まれます。

親プロセスのPIDを「PPID(Parent PID)」と呼びます。

# PPID付きでプロセスを表示 [user@web01 ~]$ ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 May18 ? 00:00:04 /usr/lib/systemd/systemd --switched-root root 440 1 0 May18 ? 00:00:00 /usr/lib/systemd/systemd-journald root 1234 1 0 May18 ? 00:00:00 /usr/sbin/sshd -D root 2010 1234 0 09:00 ? 00:00:00 sshd: user [priv] user 2015 2010 0 09:00 ? 00:00:00 sshd: user@pts/0 user 2345 2015 0 09:00 pts/0 00:00:00 -bash user 3456 2345 0 09:15 pts/0 00:00:00 ps -ef

上の出力を読むと、bash(PID 2345)の親はsshd子プロセス(PID 2015)で、その親はsshd(PID 1234)、その親はsystemd(PID 1)であることが分かります。

すべてのプロセスを遡ると、最終的にPID 1のsystemd(古いLinuxではinit)にたどり着きます。systemdが「全プロセスの祖先」となる仕組みです。

ツリー状に親子関係を見るには pstree が便利です。

# 親子関係をツリー表示 [user@web01 ~]$ pstree -p systemd(1)-+-NetworkManager(720) |-chronyd(388) |-sshd(1234)-+-sshd(2010)---sshd(2015)---bash(2345)---pstree(3789) |-systemd-journald(440) |-systemd-logind(450)

プロセスの状態(State)を読む

pstop の出力にある「STAT」または「S」列は、そのプロセスが現在どんな状態にあるかを示しています。状態の意味を理解できると、サーバーが重い原因の切り分けが一気に楽になります。
記号 状態名 意味
R Running 実行中、または実行可能(CPUを使用または待機)
S Sleeping 割り込み可能なスリープ状態(一般的に待機中のプロセス)
D Uninterruptible Sleep 割り込み不可のスリープ。多くはディスクI/O待ち。kill -9でも止まらないケースあり
Z Zombie 処理は終了したが、親プロセスが終了ステータスを回収していない状態
T Stopped 停止中(Ctrl+Zやkill -STOPで止められた状態)
I Idle カーネルスレッドのアイドル状態(カーネル4.14以降)
実務で問題になるのは主にDとZです。

D状態(uninterruptible sleep):ディスクI/Oが詰まっている、NFS/CIFSマウント先が応答しない、といった場面で発生します。プロセスが止められず、サーバー全体が重くなる原因になります
Z状態(zombie):子プロセスが終了したのに親プロセスが wait() で回収していない状態。少数なら問題なし、大量に増えるとPID枯渇の懸念

セミナーで受講生からよく聞かれる質問が、「topでD状態のプロセスをkillできない、どうすればいい?」というものです。結論から言えばkillでは止まりません。原因(多くはストレージ側)を解消するか、最後の手段として再起動するしかないのが実情です。

プロセスを終了させる(killとシグナル)

プロセスを終了させたい時は kill コマンドにPIDを渡します。kill は「殺す」というよりは「シグナルを送る」というのが正確な動作です。

# プロセスに終了シグナル(SIGTERM、デフォルト)を送る [user@web01 ~]$ kill 3456 # 強制終了(SIGKILL、9番)を送る [user@web01 ~]$ kill -9 3456 # シグナル名でも指定可能 [user@web01 ~]$ kill -TERM 3456 [user@web01 ~]$ kill -KILL 3456 # 同名プロセスをまとめて終了 [user@web01 ~]$ pkill nginx # シグナル一覧 [user@web01 ~]$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 9) SIGKILL 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP

実務で覚えておくべきシグナルは下記の4つです。
シグナル 番号 用途
SIGTERM 15 終了要求(デフォルト)。プロセスにクリーンアップの猶予を与える
SIGKILL 9 強制終了。プロセスは無視できない。最後の手段
SIGHUP 1 設定リロード(多くのデーモンが対応)
SIGSTOP 19 一時停止(fgまたはSIGCONTで再開)
20年以上Linuxサーバーを運用してきた経験から言うと、いきなり kill -9 を使うのはアンチパターンです。データベースやWebサーバーは、SIGTERMを受け取った時にバッファのフラッシュやコネクションのクローズを行います。SIGKILLで強制終了するとそれが省略され、データ破損やリソース漏洩の原因になります。まずは kill(SIGTERM)を試して、応答がない時だけ kill -9 に進むのが鉄則です。

プロセスとスレッド・ジョブの違い

混同しやすい3つの用語を整理しておきます。
用語 意味 確認コマンド
プロセス 実行中のプログラム。独立したメモリ空間を持つ ps aux
スレッド プロセス内部の実行単位。同じメモリ空間を共有する ps -eLf または top -H
ジョブ シェルが管理する起動単位(&でバックグラウンド実行、Ctrl+Zで停止など) jobs
プロセスは「家」、スレッドは「同じ家に住む家族(メモリを共有)」、ジョブは「シェルからの呼び出し札」というイメージで覚えると整理しやすいです。

トラブルシュート・「fork: Resource temporarily unavailable」が出る

新規プロセスを起動しようとして上記のエラーが出る場合、多くはPID/プロセス数の上限に達しています。

# ユーザーごとのプロセス数上限を確認 [user@web01 ~]$ ulimit -u 4096 # 現在のプロセス数を確認 [user@web01 ~]$ ps -u $(whoami) | wc -l 234 # システム全体のPID上限を確認 [user@web01 ~]$ cat /proc/sys/kernel/pid_max 4194304 # ユーザー上限を上げる(恒久設定は/etc/security/limits.conf) [user@web01 ~]$ ulimit -u 8192

ゾンビプロセスが大量に溜まっている場合もこのエラーが出ます。ps aux | awk '$8 ~ /Z/ {print}' でZ状態のプロセスを確認してください。

本記事のまとめ

Linuxのプロセスは、サーバー運用のすべての基礎です。今回の要点をコマンド一覧でまとめます。
やりたいこと コマンド
全プロセスを表示 ps aux または ps -ef
リアルタイムでプロセスを監視 top または htop
親子関係をツリー表示 pstree -p
特定の名前のプロセスを検索 pgrep -l プロセス名
プロセスに終了シグナルを送る kill PID
プロセスを強制終了 kill -9 PID
同名プロセスをまとめて終了 pkill プロセス名
スレッド表示 ps -eLf または top -H
■関連記事
psコマンドの詳細はこちら
killコマンドの詳細はこちら
killallコマンドの詳細はこちら
すべてのプロセスを表示する
デーモンプロセスも含めて表示する
プロセスの状態を詳細に表示する
プロセスの状態を表示する
プロセスの親子関係を含めて表示する
プロセスをツリー状に表示する
プロセスをハングアップさせる
プロセスを強制終了する
プロセスツリーをグラフィカルに表示する
ユーザ名を含めて実行プロセスを表示する
実行中のプロセスのみ表示する
実行中のプロセスを終了する
特定のプロセスの状態のみを表示する
特定コマンドのプロセスをすべて終了する

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

登録10秒/合わなければ解除3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。