Linux入門:コマンド操作のきほん
プロセスとは何か
起動したはずのアプリが、動いているのか分からない
デプロイしてサーバーを起動したのに、ブラウザからは応答がない。ログにも何も出ていない。このとき最初に確かめたいのは、そのプログラムが今このマシンで走っているかどうかです。そもそも走っていないのか、走っているのに詰まっているのかで、次の一手はまったく変わります。
Linux はこれを、プロセスという単位で管理しています。走っているものは必ずプロセスとして数えられていて、走っていないものは 1 つも数えられていません。
プログラムは設計図、プロセスは建った家
/usr/bin/python3 はディスクに置かれたファイルで、これ自体は何もしません。起動するとメモリの領域と番号が割り当てられ、動く実体が生まれます。この実体がプロセスです。
ターミナル
$ pgrep -a python3
2100 python3 /app/worker.py
2101 python3 /app/worker.py同じファイルを 2 回起動すれば、プロセスは 2 つできます。それぞれ別のメモリを持っていて、片方の変数がもう片方から見えることはありません。だから「python3 を止めたい」という言い方は曖昧で、止める対象は必ず番号で指します。
この番号を PID と呼びます。マシンの中で重複しない番号で、止めるときも資源の使用量を調べるときも、常にここが入口になります。自分が今打っているシェル自身の PID はシェル変数 $$ に入っていて、その親の PID は $PPID に入っています。
番号が分かれば、そのプロセスの中身はファイルとして覗けます。
ターミナル
$ ls /proc/2100/
cmdline cwd environ exe fd limits statuscmdline に起動時のコマンド行、cwd にどのディレクトリで動いているか、status にメモリの使用量が入っています。この後に出てくる道具は、どれも結局ここを読んで整えているだけです。
すべてのプロセスは 1 本の木につながっている
プロセスは、既にあるプロセスから枝分かれして生まれます。生んだ側の番号を PPID として持つので、親をたどっていくと必ず 1 番に行き着きます。
ターミナル
$ pstree -p | head -4
systemd(1)
├─sshd(890)───sshd(1234)───bash(1235)───vim(1300)
└─cron(901)ログインすると sshd の子として自分のシェルが生まれ、そのシェルの子として打ったコマンドが生まれる、という積み重なりです。この形を知っていると、止めたいものが枝の先なのか根元なのかを判断できます。Web サーバーのように親が子を作り直す作りだと、子を止めても親がすぐ新しい子を立てるので、いつまでも終わりません。
終わったのに消えないものがある
プロセスは終了するとき、終了コードを親に渡します。親がそれを受け取るまで、記録だけがその場に残り続けます。この状態をゾンビと呼びます。
一瞬なら普通のことですが、数が増え続けているなら、親のプログラムに受け取り忘れがあります。ゾンビ自体はメモリも CPU も使いませんが、PID の在庫を消費するので、放置すると新しいプロセスを作れなくなります。
ゾンビは止められません。既に終わっているので、いくら終了を命じても何も起きません。消したいときは、受け取っていない親のほうを止めます。親がいなくなった子は 1 番のプロセスが引き取り、そこで回収されます。