linux2.6.3的forget_original_parent()函数分析

Posted on 2012-12-20 22:50  vv1133  阅读(728)  评论(0编辑  收藏  举报

(2011-02-04 16:22) 

如果父进程在子进程之前退出,linux会重新为该父进程的所有子进程找到新的父亲。否则这些孤儿进程就会在退出时成为永远的僵死进程(wait4函数没有执行,僵死进程的进程描述符和栈空间不能释放)

父进程退出时会给子进程在当前进程组内找一个进程作为父亲,如果没找到就让init做它们的父亲。

在父进程do_exit()最终会调用forget_original_parent()为孤儿进程找到父亲。

 

forget_original_parent()定义在:linux/kernel/exit.c

 

了解这个函数得区分几种子进程:

1    parent == real_parent 的子进程

     这是本进程的子进程,并且没有被ptrace,处于本进程的children list上。

2   parent == father && parent != real_parent的子进程

    被本进程ptrace的其它进程的子进程,处于本进程的children list上。

3   real_parent == father && parent != real_parent的子进程

    本进程的子进程,但正在被其它进程ptrace,处于本进程的ptrace_children list上。

 

 

 

 577/* 

 578 * When we die, we re-parent all our children.

 579 * Try to give them to another thread in our thread

 580 * group, and if no such member exists, give it to

 581 * the global child reaper process (ie "init")

 582 */


 583static inline void forget_original_parent(struct task_struct * father)

 584{

 585   struct task_struct *p, *reaper = father;

 586   struct list_head *_p, *_n;

 587

 588   reaper = father->group_leader;/*选择进程组组长为新父亲*/

 589   if (reaper == father)/*如果自己就是进程组组长 则选择init进程为新父亲*/

 590     reaper = child_reaper;

 591

 592 /*

 593 * There are only two places where our children can be:

 594 *

 595 * - in our child list

 596 * - in our ptraced child list

 597 *

 598 * Search them and reparent children.

 599 */


 600   list_for_each_safe(_p, _n, &father->children) {/*遍历children list*/

 601   p = list_entry(_p,struct task_struct,sibling);

 602   if (father == p->real_parent) {/*如果退出的进程是真正的父亲*/

 603     choose_new_parent(p, reaper, child_reaper);/*选择新父亲*/

 604     reparent_thread(p, father, 0);/*设置新父亲*/

 605   } else {/*否则是就是被跟踪的进程*/

 606     ptrace_unlink (p);/*解除与退出进程的父子关系*/

 607     if (p->state == TASK_ZOMBIE && p->exit_signal != -&&

 608           thread_group_empty(p))

 609       do_notify_parent(p, p->exit_signal);/*向新父进程发送信号*/

 610     }

 611   }

 612   list_for_each_safe(_p, _n, &father->ptrace_children) {/*遍历ptrace children list*/

 613     p = list_entry(_p,struct task_struct,ptrace_list);

 614     choose_new_parent(p, reaper, child_reaper);/*选择新父亲*/

 615     reparent_thread(p, father, 1);/*设置新父亲*/

 616   }

 617}

 

感谢http://blogold.chinaunix.net/u1/55599/showart_1120377.html

Copyright © 2024 vv1133
Powered by .NET 8.0 on Kubernetes