Linuxの備忘録とか・・・(目次へ)Linuxの備忘録とか・・・(目次へ)親が無い場合のゾンビの扱いゾンビ状態とは、親プロセスが子プロセスがどれくらいCPUを使用したとか等の統計情報を取得するために、子プロセスが親プロセスに終了シグナルを送信する間の状態でした。なると、子プロセスより親プロセスがすでに終了していた場合、あるいは子プロセスがゾンビ状態で親がwait関数でその処理をしないまま終了してしまった場合、子プロセスは永久にゾンビ状態ということになるわけですが。下記サンプルは上記の2つのことを確認するものです。子プロセスがゾンビ状態にもかかわらず親がその処理をしないで終了してしまった場合。0;}子プロセスが終了した後の親プロセスのpsコマンドでは、子プロセスががゾンビになっています。<defunct>改めてpsしてみるとゾンビが無くなっています。ps子プロセスの終了前に親プロセスが終了してしまった場合。0;}親プロセスが終了し、子プロセスのみ動作しています。ps子プロセスはゾンビになっていません。psどちらにしても子プロセスは最終的にはゾンビになっていないようです。補足fork()で子プロセスを作成すると、親より先に実行されます。通常子プロセスはexecでメモリー空間を破棄し、新規に割り当てることになります。fork()では実メモリーは割り当てません。COWで書き込み処理発生毎に割り当てるものです。従って先に親プロセスが実行し、書き込み処理が発生毎に、親プロセス用にCOWで新規にメモリーを割り当てることになると、子プロセスがexec関数で全てのメモリーを破棄し新規に割り当てる可能性が高いことを考えると、メモリ割り当ての2度手間です。従って親より子プロセスが先に動作するようにスケジュールされるようです。プロセス終了時、do_exit関数から親プロセスに知らせるためにexit_notify関数がコールされます。そこからforget_original_parent関数で、終了しようとするプロセスを親とする子プロセスの親を繋ぎかえる事で、上記の処理を実現しています。*fatherは、終了プロセスです。find_new_reaper関数で終了プロセスに代わる親を取得します。終了プロセスを親に持つ全子プロセスに対して、親を差し替えています。p->real_parentは本当の親で、p->parentは終了シグナルを送信する親です。通常この2つは同じプロセスですが、デバッガで動作されている場合、p->parentはデバッガプロセスであったりします。father)で、そのプロセスが終了プロセスの場合のみ、新規の親に差し替えています。reparent_thread関数で、親子リストのp->siblingをp->real_parent->childrenに繋ぎかえています。p->real_parentは新規の親です。これで親が代わりました。reparent_thread関数では、他にこのプロセスがスレッドで、しかも既にゾンビ状態だったらこの関数から新規の親に終了シグナルを送信しています。&ptrace_dead);}find_new_reaper関数で新しい親を取得します。終了プロセスにスレッド(CLONE_THREADで作成されたプロセス)があるか調べます。あればしかもそのプロセスがゾンビ状態でないなら、それを親といたします。終了プロセスがプロセスIDのネームスペースの元親であるなら、新規の親を、このネームスペースの元親といたします。これはプロセス作成時CLONE_NEWPIDで作成したプロセスが設定されていると思います。init_pid_ns.child_reaperで、init_pid_nsのネームスペースの元親すなわちinitにしています。&init_pid_ns))で、削除プロセスのネームスペースがinit_pid_nsでないことです。これだと終了プロセスがinitになってしまいます。削除プロセスがネームスペースの元親でない場合、この元親を新規の親としています。CLONE_NEWPIDで作成していないプロセスは、initのネームスペースの元親、すなわちinitということになります。従って、この親が最終的に親がいなくなったプロセスの親となって、それらの終了処理を行います。削除されないinitが最終的には親になってくれるわけで、どのような状態削除過程であれ、ゾンビプロセスの処理が担保されるということです。ノースAdsense広告情報が設定されていません。