避免僵尸进程的三种方法
在unix系统中,如果一个子进程终止了,而父进程又没有对子进程进行wait/waitpid,那么子进程就会成为一个僵尸进程。
用命令ps -ef | grep zombie可以查看系统中是否出现僵尸进程。
僵尸进程是无法用kill 杀死,因为进程已经不存在了,但却在进程表里面占据一个项。如果当系统中出现过多的僵尸进程,
那么系统将无法再开启另外的进程,因为进程表已经满了。这个时候就只有重新启动,但reboot是没有用的,因为系统要执行reboot必须要创建进程。这是让人非常恼火的事情。
避免僵尸进程
1.wait/waitpid
程序通过wait/waitpid等待子进程结束,并清理进程表.
2.两次fork
对于一些父进程不希望等待子进程结束的程序,可以通过两次fork来避免僵尸进程
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0)
{
perror(”fork”);
}
else if (pid == 0)
{ // 第一个子进程
pid = fork();
if (pid < 0)
{
perror(”fork”);
}
else if (pid > 0)
{
exit(0); //第二个子进程的父进程终止(第一个子进程)
}
sleep(2); //保证父进程优先运行(第一个子进程)
exit(0); //第二个子进程终止
}
if (waitpid(pid, NULL, 0) != pid) //等待第一个子进程
perror(”fork”);
exit(0); //第一个父进程终止
}
当父进程比子进程先终止时,子进程会被init进程接管,当子进程终止后会被init清理。
3.通过对SIGCHLD信号处理
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf(”child %d terminated\n”, pid);
}
return;
}
int main(void)
{
int rc;
rc = 0;
signal(SIGCHLD, &sig_chld);
return (rc);
}
在子进程终止时,父进程会收到SIGCHLD信号,可以在这个时候进行处理。也可以忽略此信号。但是忽略SIGCHLD信号并不是对所有的系统都有用
最后更新:2017-01-04 22:34:34