您的位置:首页 > 运维架构 > Linux

linux僵尸进程的处理

2014-05-03 14:40 344 查看

Linux僵尸进程的处理

一.Linux僵尸进程的出现

僵尸进程是已经结束的进程,但是它的进程描述符还在进程表中,它的内存等相关资源则被释放了。它不能执行任何动作,没有可执行代码,也不能被调度,仅在进程表中保留了一个位置。

一个进程退出的时候,父进程会收到SIGCHLD信号,一般在这个信号执行函数中执行wait()或者waitpid(),该两函数处理子进程的退出。在子进程退出,到父进程执行该两函数前的时间段,该子进程即被称为僵尸进程。

如果父进程一直没有调用 wait()或者waitpid(),那么该进程则一直保持僵尸状态。

二.Linux僵尸进程的处理

2.1 改写父进程,在父进程中接收SIGCHLD信号,在信号处理函数中执行wait();

2.2 杀死父进程,则僵尸进程将交给新的进程中负责清除;

2.3 在创建子进程之前,调用函数signal(SIGCHLD, SIG_IGN),将子进程退出信号完全忽略,忽略该信号,则子进程将全然不顾的退出了。

三.具体实例

void child_test()

       {

           pid_t cpid, w;

           int status;

           int i;

           setup_signals();//here init SIGCHLD signal
 //first method

       
  // signal(SIGCHLD, SIG_IGN);            //second method
    

           cpid = fork();

           if (cpid == -1)

          {

               perror("fork");

               exit(EXIT_FAILURE);

           }

 

           if (cpid == 0)  //child process

          {                        

 i = 0;

               for(;;)

               {

               i++;

               if(i ==10)

              {

                     printf("this is end of a thread\n");

                     exit(0);

              }

           

               printf("Child PID is %ld\n", (long) getpid());

              sleep(2);

               }

        

           }

           else            //parent process

           {            /* Code executed by parent */

           /*

               if(wait(NULL) == -1)

              {

              perror("fail to wait");

              exit(1);

              }

            */

#if 0                     
//third method

              do {

                   w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);

                   if (w == -1) {

                       perror("waitpid");

                       exit(EXIT_FAILURE);

                   }

 

                   if (WIFEXITED(status)) {

                       printf("exited, status=%d\n", WEXITSTATUS(status));

                   } else if (WIFSIGNALED(status)) {

                       printf("killed by signal %d\n", WTERMSIG(status));

                   } else if (WIFSTOPPED(status)) {

  printf("stopped by signal %d\n", WSTOPSIG(status));

                   } else if (WIFCONTINUED(status)) {

                       printf("continued\n");

                   }

               } while (!WIFEXITED(status) && !WIFSIGNALED(status));

               exit(EXIT_SUCCESS);

#endif

            }

 

       }

 

static void

setup_signals()

{

    struct sigaction sa;  

    sigemptyset(&signals_handled);

    sigaddset(&signals_handled, SIGCHLD);

 

#define SIGNAL(s, handler)  do { \

       sa.sa_handler = handler; \

       sigaction(s, &sa, NULL);  \

    } while (0)

 

    sa.sa_mask = signals_handled;

    sa.sa_flags = 0;

    SIGNAL(SIGCHLD, chld);

 

}

 

static void chld(int sig)

{

        int     status;

        pid_t   pid;

  

        pid = waitpid(0,&status,0);

        printf("chid exit----pid=%d-----\n", pid);

 

        if (WIFEXITED(status))

        {

               printf("exited, status=%d, pid=%d\n", WEXITSTATUS(status), pid);

                return;

        }

}

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: