關於孤兒進程和殭屍進程的實踐

首先關於孤兒進程 

processA   processB   processC

 

ps -ef|grep process

sroot     9665 24982  0 23:42 pts/0    00:00:00 /bin/bash ./processA.sh

sroot     9666  9665  023:42 pts/0    00:00:00 /bin/bash./processB.sh

sroot     9667  9666  023:42 pts/0    00:00:00 /bin/bash./processC.sh

 

  24982  -> 9665 /processA.sh ->9666 ./processB.sh ->9667 ./processC.sh

 

24982是INIT下/bin/bash .

[sroot@AAEP7151 24982]# pwd

/proc/24982  

[sroot@AAEP7151 24982]# ll

total 0


lrwxrwxrwx. 1 sroot root 0 Jun 22 23:45 cwd -> /home/craft/shell

-r--------. 1 sroot root 0 Jun 22 23:45 environ

lrwxrwxrwx. 1 sroot root 0 Jun 22 23:32 exe -> /bin/bash


 

[sroot@AAEP7151 24982]# ps -ef |grep 24982

sroot     9665 24982  0 23:42 pts/0    00:00:00 /bin/bash ./processA.sh

sroot    19995  2740  023:47 pts/1    00:00:00 grep 24982

sroot    24982 24935  0 23:32 pts/0    00:00:00 bash

 

 

 

之後,kill -9 processB AC的變化

 

[sroot@AAEP7151 24982]# ps aux |grep process

sroot    17693  0.0 0.0 106104  1172 pts/0    S+  00:22   0:00 /bin/bash./processA.sh

sroot    17694  0.0 0.0 106104  1172 pts/0    S+  00:22   0:00 /bin/bash./processB.sh

sroot    17695 32.8  0.0 106108 1192 pts/0    S+   00:22  0:01 /bin/bash ./processC.sh

 

 

 ps aux |grep process

只剩下一個/processC.shAB 都不見了

 

sroot    17695 36.2  0.0 106108 1192 pts/0    R    00:22  0:12 /bin/bash ./processC.sh

也就是B死掉的時候,會去通知他的父進程A

本身A的存在就是等待B 完成的,所以B死掉,A也釋放了。

但是C並不知道。

這個時候A不停的繼續跑,並且無法用ctrl+c結束。

知道kill -9 processC的進程號。

 

 

這個時候並不會產生殭屍進程

此時,C就是孤兒進程。

 

如何產生殭屍進程

 

首先,殭屍進程是由於父進程沒有回收子進程。

父進程會使用wait函數來等待子進程若子進程結束,用這個函數來回收子進程。

 

 

 

 

#include <stdio.h>

#include <sys/types.h>

#include <time.h>

int main()

{

    //fork a child process

   pid_t pid = fork();  產生一個子進程。新產生的子進程同樣用這個代碼。這樣就會有兩個程序在使用同一個代碼運行。

 

   if (pid > 0)   //parentprocess父進程進入這個if判斷

    {

        printf("in parentprocess, sleep for one miniute...zZ...\n");

        struct timeval tv;

   gettimeofday(&tv,NULL);

   printf("parent microsecond:%ld\n",tv.tv_sec*1000000 +tv.tv_usec);  //微秒 輸出當前的時間

        sleep(60);

        printf("aftersleeping, and exit!\n");

       gettimeofday(&tv,NULL);

    printf("parentmicrosecond after sleeping:%ld\n",tv.tv_sec*1000000 + tv.tv_usec);  //微秒

 

                                                                                                            重新輸出sleep之後的時間

}

   else if (pid == 0)          子進程進入這個if判斷語句

 

  {

        //child process exit,and to be a zombie process

               printf("in child process, and exit!\n");

 

                 structtimeval tv;

                gettimeofday(&tv,NULL);

            printf("child microsecond:%ld\n",tv.tv_sec*1000000 +tv.tv_usec);  //微秒

 

 

                                                                     輸出進入到子進程的時間

    }

 

}

 

gcc指令編譯

[root@localhost test]# gcc zombie1.c -o zombie1

 

[root@localhost test]# ./zombie1  運行

運行結果如下

 ./zombie1

in parent process, sleep for one miniute...zZ...父進程先進入第一個判斷語句,輸出時間

parent microsecond:1498469853526179

in child process, and exit!    子進程進入判斷語句,輸出時間

child microsecond:1498469853526404

after sleeping, and exit!

parent microsecond aftersleeping:1498469913532272   父進程結束sleep,輸出時間,這個時間跟第一個輸出時間相差爲60s

 

 wKiom1lQatCDZgK4AACW5wwnIcg677.png-wh_50

 

 

ps查看進程情況

[root@localhost test]# ps aux |grep zombie

root       3445  0.0 0.0   3924   416 pts/2   S+   05:37   0:00 ./zombie1

root       3446  0.0 0.0      0     0 pts/2   Z+  05:37   0:00 [zombie1]<defunct>

 

出現一個殭屍進程

[root@localhost test]# ps -ef |grep zomb

root       3445   3024 0 05:37 pts/2    00:00:00./zombie1

root       3446   3445  0 05:37 pts/2    00:00:00 [zombie1] <defunct>

從進程ID能看出這個殭屍進程是zombie的子進程


改進程序,來更好的觀察由於父進程是否調用wait帶來的結果。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


int main()

{

    int i = 0;

    char cCmd = 'a';

    char cTmp = 'a';

    printf("process start with pid: %d\n", getpid());

    pid_t pid = fork();

    switch (pid)

    {

    case 0:

        {

            printf("child_process start with pid: %d\n", getpid());

            printf("child_process exit\n");

            exit(1);

        }

        break;

    case -1:

        break;

    default:

        {

            while (1)

            {

                printf("Input 'q' to exit without recycle the resource of child and will generate zombile process.\n");

                printf("Input 'Q' to recyle resource of child.\n");

printf("No matter q or Q , the parent process will exit .\n");

                cCmd = getchar();

                while ((cTmp = getchar()) != '\n');

                if (cCmd == 'q')

                {

                    printf(" exit without recycle the resource of child ,generate zombile process.Please use ps command to check\n");

break;

                }

                else if (cCmd == 'Q')

                {

                   printf(" Parent process will  recycle the child resource .wait child_process to exit\n");

                    wait(NULL);

                    printf("Child process was recycled ,the zombile process was clear.press any key to continue...\n");

                    cTmp = getchar(); 

                    while ((cTmp = getchar()) != '\n');

                    break;

                }

                else

                {

                    printf("You input %c. can not be recognized by this program  Please reinput\n", cCmd);

                }

            }

        }

        break;

    }

    printf("Parent_process exit\n");

    return 0;

}


設置了判斷語句讓用戶輸入,在子進程結束的時候,產生殭屍進程。

若用戶輸入q,則調用wait函數回收該殭屍進程父進程再退出。

若用戶輸入Q,則不調用wait函數回收,直接退出。

[root@localhost fish]# ./zombile

process start with pid: 23216

Input 'q' to exit without recycle the resource of child and will generate zombil

Input 'Q' to recyle resource of child.

No matter q or Q , the parent process will exit .

child_process start with pid: 23217

child_process exit

此時查看進程發現產生了殭屍進程

[root@localhost ~]# ps -ef |grep zombile

root     23216 22233  0 17:34 pts/1    00:00:00 ./zombile

root     23217 23216  0 17:34 pts/1    00:00:00 [zombile] <defunct>

root     23223 22391  0 17:34 pts/2    00:00:00 grep zombile

Q

 Parent process will  recycle the child resource .wait child_process to exit

Child process was recycled ,the zombile process was clear.press any key to continue...

運行該程序發現,在使用wait之後,殭屍子進程就消失了。

[root@localhost ~]# ps -ef |grep zombile

root     23216 22233  0 17:34 pts/1    00:00:00 ./zombile

root     23225 22391  0 17:34 pts/2    00:00:00 grep zombile

只剩下父進程自己。


此時如果直接退出該程序,退出父進程,子進程也會跟着消失,可見,清除父進程是清楚殭屍子進程的方法之一。


  • killdefunct進程方法有二:

  • 1,重啓服務器電腦,這個是最簡單,最易用的方法,但是如果你服務器電腦上運行有其他的程序,那麼這個方法,代價很大。
             
      所以,儘量使用下面一種方法

  • 2,找到該defunct殭屍進程的父進程,將該進程的父進程殺掉,則此defunct進程將自動消失。


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