1. 程式人生 > >模擬實現——殭屍和孤兒程序

模擬實現——殭屍和孤兒程序

一 、殭屍程序

 1.   我們知道程序狀態有:R執行狀態,S睡眠狀態(可中斷睡眠狀態),D磁碟休眠狀態(不可中斷睡眠狀態),T停止狀態,X死亡狀態。還有一種比較特殊的就是殭屍狀態(Z)了。

 2.    Z(zombie)--殭屍程序

    <1>當子程序退出,父程序無法讀取到子程序退出的返回碼時就會產生殭屍程序。父程序還在執行,子程序進入殭屍狀態。

    <2>殭屍程序以程序中止的狀態保持在程序表中,並且一直會等待父程序讀取退出狀態程式碼。

下面我們來實現一個簡單的殭屍程序:

test.c程式碼部分:

1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 int main()
  5 {
  6     pid_t id=fork();
  7     if(id < 0){
  8         //error
  9         perror("fork");
 10         return 1;
 11     }
 12     else if( id == 0 ){//child
 13         printf("child[%d] is begin Z!!!\n",getpid());
 14         sleep(5);
 15         exit(EXIT_SUCCESS);
 16     }
 17     else{//parent
 18         printf("parent[%d] is sleeping!!!\n",getpid());
 19         sleep(30);
 20     }
 21 
 22     return 0;
 23 }

makefile:

  1 test:test.c                                                                                                                                              
  2     gcc -o test test.c
  3 
  4 .PHONY:clean
  5 clean:
  6     rm -f test

在此終端下編譯程式碼:

編譯時在另一個終端啟動監控:

我們可以看到 ,子程序在睡眠後退出,由於父程序不讀取其退出狀態,子程序進入Z狀態。

3.殭屍程序的危害

   <1>我們知道,父程序創建出子程序,是想讓子程序完成某項工作,那麼子程序退出時就要告訴父程序,你交給我的工作,我完成的如何。可是如果父程序一直不讀取子程序的退出狀態,那麼子程序就會一直處於Z狀態。因此,程序的退出狀態必須被維持下去。

維護程序的退出狀態本質上是要用資料維護,這個資料也屬於程序資訊,因此資料會儲存在PCB中。如果Z狀態一直不退出,那麼PCB就要一直維護程序的退出狀態。

如果一個程序創建出很多子程序,但它就是不讀取子程序的退出狀態,那麼由於PCB佔用記憶體,只開闢空間而不回收就會造成記憶體資源的浪費,進而造成記憶體洩漏。因此,父程序要及時回收子程序,避免記憶體洩漏,對系統造成威脅。

二、 孤兒程序

1.父程序先退出,子程序就被稱為“孤兒程序”。

     父程序退出後,子程序被1號程序init領養,init程序對孤兒程序完成狀態收集工作。

實現:

  1 #include<stdio.h>                                                                                                                                        
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 
  5 int main()
  6 {
  7     pid_t id =fork();
  8     if(id < 0){
  9         perror("fork");
 10         exit(0);
 11     }
 12     else if(id > 0){//parent
 13         printf("I am parent,pid:%d\n",getpid());
 14         sleep(5);
 15         exit(0);
 16     }
 17     else{//child
 18         printf("I am child,pid:%d\n",getpid());
 19         sleep(10);
 20         exit(0);
 21     }
 22     return 0;
 23 }

編譯並且在另一個終端啟動監控:

可以看出,當父程序退出後,子程序的ppid變為了1,這樣,當一個孤兒程序結束了其生命週期的時候,init程序就會處理它的一切善後工作,因此一般來說,孤兒程序不會有什麼危害。