孤儿进程造成的进退维谷

如果父进程在子进程之前退出,必须有机制来保证子进程能找到一个新的父亲,否则这些成为孤儿的进程在退出时将永远处于僵死状态,白白耗费内存。对于这个问题解决方法是给子进程在当前线程内找一个线程作为父亲,如果不行,就让init做它们的父亲。在do_exit() 中会调用exit_notify(),该函数会调用forget_original_parent(),而后调用 find_new_reaper()来执行寻父过程。

p.s. 在每个task_struct中都有一个parent指针,指向父进程task_struct。还有包含一个children的子进程链表。进程退出时,大部分清理工作都通过do_exit()(定义在/kernel/exit.c)来完成。 find_new_reaper中找到合适的养父进程后,只需要遍历children链表并为链表中每一个task_struct设置新的父进程(parent指针)即可。

1
2
3
4
5
6
7
8
9
reaper = find_new_reaper(father);
list_for_each_entry_safe(p, n, &father->children, sibling) {
p->real_parent = reaper;
if (p->parent == father) {
BUG_ON(p->ptrace);
p->parent = p->real_parent;
}
reparent_thread(p, father);
}