殭屍進程的產生原因

在Linux系統中,殭屍進程是已經執行完畢,但是沒有被父進程回收的子進程。判斷殭屍進程的一個方法是使用ps命令查看進程狀態。如果進程狀態是Z,說明這是一個殭屍進程。

 

在多進程的程序中,父進程會啓動若干個子進程來處理任務。當子進程退出後,除了在進程表中佔用的一個進程表項,子進程所使用的資源(文件描述符、內存等)都會被釋放。保留子進程的進程表項,是爲了把子進程的執行結果告訴給父進程。父進程調用waitpid()來得到子進程的執行結果。

如果子進程執行完畢,而父進程沒有退出,也沒有調用waitpid()來得到子進程的執行結果,這時,子進程已經不存在了,卻還佔用着一個進程表項。這樣的進程叫做殭屍進程。當父進程調用waitpid()後,殭屍進程佔用的進程表項被釋放,殭屍進程徹底消失。

如果父進程在調用waitpid前退出,子進程(包括殭屍進程)的父進程會變爲init進程。由init進程負責回收子進程,所以不會產生殭屍進程。

殭屍進程消耗的唯一資源是進程表項。也就是說,如果產生了大量的殭屍進程佔滿了進程表,系統將無法創建新的進程。除此之外,殭屍進程不會對系統造成影響。

殭屍進程不能使用kill來殺死。因爲殭屍進程已經執行完畢了,無法殺死。要消除殭屍進程,方法是找到父進程,殺死父進程。這時殭屍進程會由init收回。

下面是一個展示殭屍進程產生原因的例子。


 

/*
   展示Linux系統中殭屍進程的產生原因。
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


int main(void){

  pid_t pid;

  if ((pid = fork()) < 0){
    perror("");
    exit(0);
  } else if (pid == 0){
    exit(0);
  } else {
    char ch;
    char buffer[1024];
    int status;

    printf("See the zombie process?\n");
    printf("child process pid: %d\n", pid);
    sprintf(buffer, "ps -ef | grep %d\0", pid);
    printf("execute '%s'\n", buffer);
    system(buffer);

    waitpid(pid, &status, 0);

    printf("It's gone.\n");
    printf("execute '%s'\n", buffer);
    printf("child process (%d) exited with status: %d\n", pid, status);
    system(buffer);
  }

  return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章