阅读509 返回首页    go 微软 go Office


避免僵尸进程的三种方法

在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

  上一篇:go linux 安装sysstat使用iostat、mpstat、sar、sa
  下一篇:go Squid集群做CDN全网加速