Linux入門:コマンド操作のきほん

プロセスとは何か

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

このレッスンで分かること

  • プロセスはカーネルが実行中のプログラム実体、PID で一意に識別されます
  • 状態は R (実行中) / S (待機) / T (停止) / Z (ゾンビ) を遷移します
  • すべてのプロセスは PID 1 (init/systemd) を頂点とするツリー構造

プロセス とは

Linuxにおけるプロセスとは何か?その概念と、システムにおける役割について解説します。本レッスンでは、プロセス の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

Linux 上で動いているソフトウェアはすべて「プロセス」という単位で管理されています。Web サーバーも、データベースも、SSH のセッションも、皆さんが叩いているシェルも、いずれもカーネルから見れば一つのプロセスです。サーバーが重い、応答が遅い、メモリが枯渇している、デプロイしたアプリが立ち上がらないといったトラブルに直面したとき、最初に確認するのは「いま何のプロセスが、どれくらい資源を使って動いているか」です。プロセスというモデルを腹落ちさせておくと、以降の ps, top, kill, バックグラウンド実行といった話が一本の糸でつながって見えるようになります。

プロセスの概念を曖昧にしたまま運用していると、たとえば「プロセスを kill したつもりが子プロセスが残ってポートを掴み続ける」「再起動したらゾンビプロセスが大量にいる」といった現象に対処できません。本レッスンでは、プロセスが生まれてから消えるまでの一連のライフサイクルと、PID / PPID / UID といった重要な属性を整理します。

プロセスを一言でいうと「カーネルがいま実際に走らせているプログラムの実体」です。サーバーもシェルも、すべてこの単位で動いています。

プロセスとプログラムの違い

似ているようで違う言葉として「プログラム」と「プロセス」があります。混同しがちなので最初に整理しておきます。

用語何を指すか
プログラムディスク上の実行ファイル (静的)/usr/bin/python3, /bin/bash
プロセスプログラムをカーネルが実行している状態 (動的)いま動いている python3 のインスタンス
スレッドプロセス内部の実行単位nginx の worker スレッド

プログラムは設計図、プロセスは設計図に従って組み上がった実体だとイメージすると分かりやすいです。同じプログラムを 3 回起動すれば、3 つの独立したプロセスが生まれます。それぞれが独自のメモリ空間とファイルディスクリプタを持っており、お互いの状態は直接見えません。

プロセスの属性

Linux のプロセスには、必ずいくつかの属性が紐づきます。

ターミナル

ps -o pid,ppid,uid,stat,cmd -p $$ # PID PPID UID STAT CMD # 1234 789 1000 Ss /bin/bash

主要な属性は次のとおりです。

属性意味
PIDプロセス ID。OS 内で一意
PPID親プロセス ID。誰から起動されたか
UID実行ユーザー ID
STAT状態 (R 実行中, S 待機, Z ゾンビ, T 停止)
CMD起動コマンド

PID は番号札のようなもので、kill で対象を指定するときも、ログを追うときも常に PID を起点に動きます。PPID をたどっていくと、最終的にすべてのプロセスは PID 1 の init プロセス (systemd など) に辿り着きます。

プロセスのライフサイクル

diagram (will load when visible)

図の状態遷移を箇条書きで整理すると、次の通りです。

  • fork で親から複製されて生まれる (N → R)
  • 実行中 (R) から I/O 待ちで Sleeping (S) になる
  • I/O が完了すれば R に戻る
  • Ctrl+Z で T (Stopped) に入る
  • 子が完了後、親が wait するまでの間 Z (Zombie) になる(親が回収しなければ残り続ける)
  • 親が wait すると最終的に終了 (E)

Linux のプロセスは fork システムコールによって親から複製される形で生まれ、必要に応じて exec で別のプログラムに置き換わります。CPU 時間が割り当てられている間は R (Running)、I/O などを待っている間は S (Sleeping) になり、終了直前で親に終了コードを回収されるまでの一瞬は Z (Zombie) という状態を取ります。Ctrl+Z などで一時停止すると T (Stopped) になります。

ゾンビプロセスは「子が終わったのに親が wait してくれない」状態で発生します。短時間なら無害ですが、大量に溜まると PID テーブルを圧迫します。発見したら親プロセス側のバグを疑うのがセオリーです。

プロセスツリー

すべてのプロセスは親子関係を持っており、ツリー構造でつながっています。

ターミナル

pstree -p | head -20 # systemd(1) # ├─sshd(890)───sshd(1234)───bash(1235)───vim(1300) # └─cron(901)

たとえば SSH でログインすると sshd の子として bash が起動し、その bash の子として皆さんが叩いたコマンドが起動します。デーモン (常駐プロセス) を fork したり、ジョブを並列で起動したりすると、このツリーがどんどん広がっていきます。

プロセスを停止するときは、ツリーの末端だけ kill しても親が再生成してくる場合があります。Web サーバーのような master/worker 構成では、worker ではなく master を狙うのが定石です。

プロセス情報の在り処 /proc

ターミナル

ls /proc/$$/ | head -10 # cmdline # cwd # environ # exe # fd # limits # maps # status

Linux ではプロセスの情報が /proc/<pid>/ 配下に仮想ファイルとして見えるようになっています。/proc/<pid>/cmdline で起動引数、/proc/<pid>/status でメモリ使用量や状態、/proc/<pid>/fd で開いているファイルディスクリプタを覗けます。pstop の値も、内部的にはこの /proc を読んで作られています。

なぜプロセスを意識するのか

運用や開発の現場でプロセスを意識する典型的な場面は次のとおりです。

  • デプロイしたアプリが応答しないので、本当に起動しているか確認したい
  • メモリやCPUを食っているプロセスを特定して止めたい
  • バックグラウンドで長時間ジョブを走らせたい (バッチ処理、ML 学習など)
  • ゾンビや孤児プロセスが残っていないか定期点検したい
  • 子プロセスの終了コードを親側でハンドリングしてリトライを組みたい

これらに対処するために、次のレッスンから ps, top, kill, バックグラウンドジョブ、nohup を順に押さえていきます。

この章のポイント

ここまでの要点 プロセス = 実行中のプログラム。PID / PPID / UID / STAT。状態は R/S/T/Z。すべて PID 1 を頂点とするツリー。/proc/<pid>/ で詳細を読める。

まとめ

  • プログラムは設計図、プロセスはそれを動かしている実体である
  • プロセスは PID / PPID / UID / STAT / CMD などの属性で識別する
  • ライフサイクルは Running, Sleeping, Stopped, Zombie の状態を遷移する
  • すべてのプロセスは PID 1 を頂点とするツリー構造でつながっている
  • /proc 配下から各プロセスの情報をテキストとして読める

次のレッスン

次は psでプロセス一覧を確認する で、Linuxにおけるプロセスとは何か?その概念と、システムにおける役割について解説します を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. プロセスとは の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. プロセスとは とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

参考リンク