|
Linux中我们通常需要进行多进程编程,最常用的方法就是在主进程中采用fork的方法创建子进程,然而这个过程很容易就会产生很多僵尸进程,占用大量系统资源,甚至导致死机.......
在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程fork()之前既没安装SIGCHLD信号处理函数调用waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程,无法正常结束,此时即使是root身份kill -9也不能杀死僵尸进程。补救办法是杀死僵尸进程的父进程(僵尸进程的父进程必然存在),僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程。
避免产生僵尸进程的方法:
1)Linux中也可使用这个,在一个程序的开始调用这个函数
signal(SIGCHLD,SIG_IGN); //头文件:#include <sys/wait.h>
2)调用fork两次。以下程序 实现了这一点。
因为儿子进程先退出,孙子进程就被init接管了,实际上与最初的父进程脱离了关系,就不会僵死了
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
int main(void)
{
pid_t pid;
if ((pid = fork()) < 0)
{
fprintf(stderr,"Fork error!\n");
exit(-1);
}
else if (pid == 0) /* first child */
{
if ((pid = fork()) < 0)
{
fprintf(stderr,"Fork error!\n");
exit(-1);
}
else if (pid > 0)
exit(0); /* parent from second fork == first child */
/*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("Second child, parent pid = %d\n", getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /* wait for first child */
{
fprintf(stderr,"Waitpid error!\n");
exit(-1);
}
/*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0);
}
3)用waitpid等待子进程返回.
|
|