模擬實現——殭屍和孤兒程序
一 、殭屍程序
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程序就會處理它的一切善後工作,因此一般來說,孤兒程序不會有什麼危害。