01 / 08
一覧は平らだけれど、本当は木
前の回で ppid(親の番号)を見たよね。あなたのシェルの親は 1 番だった。
78 1 -shということは、init の下にあなたのシェルがぶら下がっていることになる。そして ps を打てば、そのシェルの下に ps がぶら下がる。
プロセスは一列に並んでいるのではなく、木の形になっているんだ。
ps の出力は番号の順に平らに並んでいるだけなので、この形が見えない。だから今回はそれを絵にする道具を使うよ。
プロセスとシグナル
INPUT · スライド
01 / 08
前の回で ppid(親の番号)を見たよね。あなたのシェルの親は 1 番だった。
78 1 -shということは、init の下にあなたのシェルがぶら下がっていることになる。そして ps を打てば、そのシェルの下に ps がぶら下がる。
プロセスは一列に並んでいるのではなく、木の形になっているんだ。
ps の出力は番号の順に平らに並んでいるだけなので、この形が見えない。だから今回はそれを絵にする道具を使うよ。
02 / 08
新しいプロセスは、必ずすでにあるプロセスから生まれるよ。
~ $ lsこのとき起きているのはこうだよ。
1. シェルが自分の複製を作る
2. 複製のほうが自分を ls に入れかえる
3. シェルは複製が終わるのを待つ
4. 終わったらプロンプトを出す
1つめを fork(枝分かれ)、2つめを exec(入れかえ)と呼ぶよ。名前は覚えなくていいけれど、親が自分をコピーして子を作るという形だけ掴んでおいてね。
これが「木になる」理由だよ。すべてのプロセスは誰かの子で、いちばん上まで辿ると必ず init(1番)に着くんだ。
そして「シェルは待つ」に注目してほしいな。この章の後半でやる & は、この待つのをやめる印なんだ。
03 / 08
pstree で木を見る木を絵にするコマンドが pstree だよ。
~ $ pstreeinit-+-crond |-sh---pstree `-syslogd読み方は単純だよ。
-+- は「ここから枝が分かれる」| は枝の続き、` `` はいちばん下の枝--- は子が1つだけこの3行に、この Linux の全体が入っているよ。init の子が3つ(crond sh syslogd)で、sh(あなたのシェル)の子が pstree 自身。
前の回で「init の子は3つ」と数えたのを覚えているかな。同じことを絵で見たわけだね。数えるより速いでしょう。
04 / 08
-p で番号を付ける番号も見たいときは -p を付けるよ。
~ $ pstree -pinit(1)-+-crond(77) |-sh(78)-+-pstree(86) | `-... `-syslogd(52)かっこの中が PID だよ。止めたいプロセスを探すときはこれだね。木の形で位置を確かめて、番号を読み取る、という流れになるよ。
次のレッスンで kill をやるとき、この形が役に立つよ。「止めたいのはこの枝の、この番号」と目で確かめられるからね。
狙いを間違えて親を止めてしまうと、その下の枝ごと巻きこむことがある。先に木を見るのが安全な手順なんだ。
05 / 08
2*[...] にまとまる同じ名前の子がいくつも並ぶと、pstree はまとめて書くよ。
~ $ sleep 30 & sleep 31 & pstreeinit-+-crond |-sh-+-pstree | `-2*[sleep] `-syslogd2*[sleep] は「sleep が2つ」という意味だよ。100個あれば 100*[sleep] になる。
ここで初めて & を使ったね。うしろで動かす印で、打ったらすぐプロンプトが返ってくるよ。詳しくはこの章の後半でやるので、いまは「木に枝を増やすための道具」と思っておいてね。
まとめて書いてくれるのは親切だよ。Web サーバーのように同じものを50個立てる作りだと、そのままでは画面が埋まってしまうからね。
1つ1つの番号が見たいときは -p を足すよ。そうすると sleep(99) のように、まとめずに全部並べてくれるんだ。
06 / 08
木が大きいときは、見たいところだけ渡せるよ。番号か、人の名前を書くんだ。
~ $ pstree $$sh---pstree~ $ pstree manabiyash---pstree渡したものから下だけを描いてくれるよ。$$ は自分のシェルの番号だったね(前の回でやったよ)。
そして大事な性質があるよ。pstree は 1 番の木しか描かないんだ。
前の回で見た [kthreadd] から下の31本、あれは 2 番から生えている別の木だよ。だから pstree には出てこないんだ。
~ $ pstree 2kthreadd-+-cpuhp/0 |-kcompactd0 `-...番号を渡せば見られるよ。この Linux には木が2本あるということだね。カーネルの木と、あなたたちの木だよ。
07 / 08
init が引き取る親が子より先に終わってしまったら、その子はどうなるんだろう。
試せるよ。かっこで囲んで動かすと、囲みのシェルが先に消えるんだ。
~ $ ( sleep 20 & )~ $ ps -o pid,ppid,args | grep "[s]leep 20" 94 1 sleep 20親が 1 になっているね。あなたのシェル(78)ではなく init だよ。
これが init のもう1つの役目だよ。親を失ったプロセスを引き取るんだ。
なぜ要るんだろう。プロセスが終わるとき、終わったことを親に伝える決まりになっているからだよ。伝える相手がいないと、終わったのに片づかない「ゾンビ」のまま残ってしまう。だから必ず誰かが親でいる必要があるんだ。
init は引き取った子の後始末を黙ってやってくれるよ。木のいちばん上にいる人は、みんなの後片づけ係でもあるんだね。
08 / 08
使う道具はこれだけだよ。
pstree 木を描くpstree -p 番号も付けるpstree $$ 自分のシェルから下だけpstree manabiya その人のぶんだけpstree 2 カーネルの木木の形は文字の絵なので、ファイルに残してから cat で見る問題が多いよ。画面が狭いときは、そのほうが読みやすいからね。
うしろで動かす & も少し使うよ。枝を増やすためだけなので、いまは意味を深く考えなくていいからね。
1つ約束だよ。kill 1 は打たないでね。1番を止めると Linux ぜんたいが止まる。この教材では止められないように守られているけれど、本物のサーバーでは本当に落ちるからね。