kakts-log

programming について調べたことを整理していきます

OSのプロセス、forkなど

海外ではapueと呼ばれていて、unixプログラミングに関して有名な詳解unixプログラミング第3版をちょくちょく読んでいます。8000円以上してめっちゃ高額ですがかなり勉強になって良い本だと思います。
プロセス周りの章を読んでいて、すごく勉強になっているので箇条書きですが簡単に整理します。

forkの使い方
1 プロセスは自身の内容を複製し、親と子で異なるコード部分を同時に実行する 
ネットワークサーバでは一般的 親はクライアントからのサービス要求を待つ。
要求が来ると親はforkを読んで子に要求を処理させる。
親は次のサービスの要求の到着を待つ状態へ戻る

2 プロセスで別のプログラムを実行したい場合 シェルでは一般的。この場合h、forkから戻った直後に子はexecを行う
forkの後につづけてexec を行う この組み合わせをspawnという操作と呼ぶ物も或る
子は入出力のリダイレクト、ユーザID、シグナルの処理方法などのプロセスごとの属性をfork と execの間で変更できる

fork失敗する理由
・プロセスがすでに多すぎる
・実ユーザのプロセス個数がシステムの制限を超えている

vfork と forkの違い
vforkだと、子がexecやexitを呼ぶまで子が先に動作することを保証する
子がこれらの関数のいずれかを呼ぶと親が動作を再会
子がこれらの2つの関数を呼ぶ前に、子が親のさらなる動作に依存する場合、デッドロック

fork後、親と子プロセスがあるのは自明
but 子の前に親が終了した場合はどうなる?
プロセスinitが、親が終了してしまった任意のプロセスの親になる

プロセスが終了した場合、カーネルは何をするか
プロセスが終了すると、カーネルはすべての生きているプロセスを対象に、終了するプロセスが現存の任意のプロセスの親か否かを調べる
もしそうなら、現存の当該プロセスの親プロセスIDをinit のプロセスIDである1に変更する
こうすることで、すべてのプロセスに親がいることを保証する


親プロセスより先に子が死んだ場合
子が完全に消えると、この終了を親がやっと検査できるようになったときには子の終了状態を取得できない
カーネルは終了した各プロセスに関する少量の情報を保持。終了したプロセスの親がwaitやwaitpidを読んだときに情報を入手できるようにする
カーネルは当該プロセスが使用していたすべてのメモリを解放しオープンしているファイルをクローズできる

プロセスが終了したのに、その親が待ち合わせを行っていないプロセス ➡ ゾンビ

psコマンドで ゾンビの場合Z 

多くの子プロセスをforkする長時間稼働のプログラムを書く時、子を待ち合わせてその終了状態を取得しない限り、それらはゾンビになる

initプロセスの子プロセスが死んだ場合どうなるか。
➡ゾンビにはならない
なぜなら、initは子が終了すると、wait関数群の一つを読んで、終了状態を取得するようになっている。このため、initはシステムにゾンビがあふれることを防いでいる