wait処理
waitは終了プロセスだけをウエイトするものでなく、プロセスがシグナル/トレースで一時停止した場合、またそこから再実行した場合においても、かかる処理を行います。waitシステムコールはdo_wait関数からdo_wait_thread関数、そして wait_consider_task関数へと渡って行きます。
do_wait関数でwaitするプロセスのスレッドグループのプロセスに対して、1つづつチェックします(__WNOTHREADオプションに依存)、do_wait_thread関数ではこのプロセスの子プロセスを調べていきます。そしてwait_consider_task関数では子プロセスに対して、終了、一時停止、再実行に応じたwait処理への関数がコールされます。
eligible_child関数で、CLON_THREDのプロセスが対象となるかどうかのチェックをします。これは指定されたオプション(__WCLONE/__WALL)との兼ね合いで決まります。
ptrace引数が0で、子プロセスがトレースされていたら対象外です。ptrace引数はdo_wait_thread関数から本関数をコールする時に指定されるもので、まずトレースされていない子プロセスを、そしてそこに対象子プロセスがなければ、本引数を1にしてトレースされている子プロセスとチェックしています。
対象プロセスがEXIT_DEAD状態だと処理する必要はありません。親プロセスが子プロセスからのSIGCHILDを無視する設定をし、子プロセス自身がみずからEXIT_DEA状態にする場合で、しかも親プロセスががwaitコールしてしまうケースを想定してのことでしょうか?
if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p))でEXIT_ZOMBIE状態のプロセスに対してwait_task_zombie関数をコールします。delay_group_leader関数はスレッドグループリーダで、そこにサブスレッドを有しているなら1を返します。従ってそうでない子プロセスが対象となるわけですが、その意味するところはわかりません。
task_is_stopped_or_traced関数で一時停止/トレースの子プロセスなら、wait_task_stopped関数を、それ以外ならwait_task_continued関数でコールします。
infopには子プロセスからの送られたシグナルの情報(シグナル番号とかプロセスID)が設定されます。stat_addrには子プロセスのexit_codeが、ruにはリソース情報(CPUどどれくらい使用したとか、ページをどれくらい要求したとか)が設定されます。
なお、wait_task_zombie関数のみ子プロセスのプロセスディスクリプタを解放します。ただしオプションが WNOWAITの時その限りではありません。
do_wait関数でwaitするプロセスのスレッドグループのプロセスに対して、1つづつチェックします(__WNOTHREADオプションに依存)、do_wait_thread関数ではこのプロセスの子プロセスを調べていきます。そしてwait_consider_task関数では子プロセスに対して、終了、一時停止、再実行に応じたwait処理への関数がコールされます。
eligible_child関数で、CLON_THREDのプロセスが対象となるかどうかのチェックをします。これは指定されたオプション(__WCLONE/__WALL)との兼ね合いで決まります。
ptrace引数が0で、子プロセスがトレースされていたら対象外です。ptrace引数はdo_wait_thread関数から本関数をコールする時に指定されるもので、まずトレースされていない子プロセスを、そしてそこに対象子プロセスがなければ、本引数を1にしてトレースされている子プロセスとチェックしています。
対象プロセスがEXIT_DEAD状態だと処理する必要はありません。親プロセスが子プロセスからのSIGCHILDを無視する設定をし、子プロセス自身がみずからEXIT_DEA状態にする場合で、しかも親プロセスががwaitコールしてしまうケースを想定してのことでしょうか?
if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p))でEXIT_ZOMBIE状態のプロセスに対してwait_task_zombie関数をコールします。delay_group_leader関数はスレッドグループリーダで、そこにサブスレッドを有しているなら1を返します。従ってそうでない子プロセスが対象となるわけですが、その意味するところはわかりません。
task_is_stopped_or_traced関数で一時停止/トレースの子プロセスなら、wait_task_stopped関数を、それ以外ならwait_task_continued関数でコールします。
static int wait_consider_task(struct task_struct *parent, int ptrace, struct task_struct *p, int *notask_error, enum pid_type type, struct pid *pid, int options, struct siginfo __user *infop, int __user *stat_addr, struct rusage __user *ru) { int ret = eligible_child(type, pid, options, p); if (!ret) return ret; if (unlikely(ret < 0)) { if (*notask_error) *notask_error = ret; } if (likely(!ptrace) && unlikely(p->ptrace)) { *notask_error = 0; return 0; } if (p->exit_state == EXIT_DEAD) return 0; if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) return wait_task_zombie(p, options, infop, stat_addr, ru); *notask_error = 0; if (task_is_stopped_or_traced(p)) return wait_task_stopped(ptrace, p, options, infop, stat_addr, ru); return wait_task_continued(p, options, infop, stat_addr, ru); }wait_task_zombie/wait_task_stopped/wait_task_continued関数の主たる処理は、引数のinfop, stat_addr, ruに統計情報を設定することにあります。
infopには子プロセスからの送られたシグナルの情報(シグナル番号とかプロセスID)が設定されます。stat_addrには子プロセスのexit_codeが、ruにはリソース情報(CPUどどれくらい使用したとか、ページをどれくらい要求したとか)が設定されます。
なお、wait_task_zombie関数のみ子プロセスのプロセスディスクリプタを解放します。ただしオプションが WNOWAITの時その限りではありません。