最近在学习linux的内核,在看完网上的一些wait4调用和do_exit调用说明后对僵尸进程的产生的缘由也有了一个大致的了解,
在此对其作个总结:
首先是do_exit()调用:
do_exit(long code)
(1) __exit_mm(tsk): //释放存储空间
(2) sem_exit();
(3) __exit_files(tsk); //释放已经打开的文件
(4) __exit_fs(tsk);
(5) exit_sighand(tsk);//释放信号处理表
(6) exit_thread();
(7) tsk->exit_code = code;
(8) exit_notify();
(9) schedule();
当一个子进程调用exit(*)调用时,会清理掉它自身的相关内存数据
exit_notify
(1)forget_original_parent:因为当前进程要“去世”,那么首先得把它所有的子进程托付给另外一个进程。如果当前这个进程是个线程(有点混乱,确切地说当前这个task实质上表示的是一个线程),那么就托服给线程组的下一个线程。否则,就托付给init进程。
(2)current->state = TASK_ZOMBIE
(3)do_notify_parent:告知父进程其子进程结束的消息
注意:在exit_notify中会将该子进程的状态标志转成zombie,僵尸!
那么我们再看看父进程需要做什么:
父进程调用wait4来清理子进程的残留信息:
sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru)
repeat:
end_wait4:
}
当父进程发现子进程发现子进程的状态为zombie时会负责清理它的遗留信息,所以在编写多进程的时候父进程在处理子进程的退出务必要使用wait相关操作,负责会使得子进程的信息不干净变成僵尸进程。