此生既入苦寒山,何妨再攀险峰!
分类:
2011-09-20 10:59:56
原文地址:linux 2.6.23孤儿进程 作者:KYlinux
forget_original_parent()定义:linux/kernel/exit.c 673/* 674 * When we die, we re-parent all our children. 675 * Try to give them to another thread in our thread 676 * group, and if no such member exists, give it to 677 * the child reaper process (ie "init") in our pid 678 * space. 679 */ 680static void 681forget_original_parent(struct task_struct *father, struct list_head *to_release) 682{ 683 struct task_struct *p, *reaper = father; 684 struct list_head *_p, *_n; 685 686 do { 687 reaper = next_thread(reaper); 688 if (reaper == father) { 689 reaper = child_reaper(father); 690 break; 691 } 692 } while (reaper->exit_state); /**next_thread(reaper)找到当前线程组另一个线程。如果if判断条件不成立,找到新线程是孤儿进程新父亲 if条件成立,那么说明当前线程组没有其他线程,那么只有init为其父进程 694 /* 695 * There are only two places where our children can be: 696 * 697 * - in our child list 698 * - in our ptraced child list 699 * 700 * Search them and reparent children. 701 */ 702 list_for_each_safe(_p, _n, &father->children) { 703 int ptrace; 704 p = list_entry(_p, struct task_struct, sibling); 706 ptrace = p->ptrace; 707 708 /* if father isn't the real parent, then ptrace must be enabled */ /**当前退出的线程不是其真正的父亲,那么必然是被跟踪的进程.否则在系统日志打印错误。 709 BUG_ON(father != p->real_parent && !ptrace); /**如果当前退出进程是其真正的父亲,为退出进程的子进程设置新的父进程 711 if (father == p->real_parent) { 712 /* reparent with a reaper, real father it's us */ 713 choose_new_parent(p, reaper); 714 reparent_thread(p, father, 0); 715 } /**如果当前EXIT_ZOMEBIE状态.父进程关系发生了改变,则应该向新的父进程发送信号 else { 716 /* reparent ptraced task to its real parent */ /**本代码进程是跟踪即将退出的进程,被挂到退出进程的子链表上,后面详细解释. _ptrace_unlink(p)解除与退出进程的父子关系(因为本进程即将退出),并挂到生父进程的子链表中。 717 __ptrace_unlink (p); 718 if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 && 719 thread_group_empty(p)) 720 do_notify_parent(p, p->exit_signal); 721 } /**如果子进程为僵尸状态,且退出时不给父进程信号就将其收集起来,到时候统一退出处理 723 /* 724 * if the ptraced child is a zombie with exit_signal == -1 725 * we must collect it before we exit, or it will remain 726 * zombie forever since we prevented it from self-reap itself 727 * while it was being traced by us, to be able to see it in wait4. 728 */ 729 if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) 730 list_add(&p->ptrace_list, to_release); 731 } /**为当前退出进程,跟踪子进程设置新的父亲 732 list_for_each_safe(_p, _n, &father->ptrace_children) { 733 p = list_entry(_p, struct task_struct, ptrace_list); 734 choose_new_parent(p, reaper); 735 reparent_thread(p, father, 1); 736 } 737} |
对BUG_ON定义: 23#ifndef HAVE_ARCH_BUG 24#define BUG() do { \ 25 printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ 26 panic("BUG!"); \ 27} while (0) 28#endif 30#ifndef HAVE_ARCH_BUG_ON 31#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0) |