a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 學(xué)院 > 操作系統(tǒng) > 正文

孤兒進(jìn)程與僵尸進(jìn)程[總結(jié)]

2024-06-28 16:00:47
字體:
供稿:網(wǎng)友

1、前言

  之前在看《unix環(huán)境高級編程》第八章進(jìn)程時候,提到孤兒進(jìn)程和僵尸進(jìn)程,一直對這兩個概念比較模糊。今天被人問到什么是孤兒進(jìn)程和僵尸進(jìn)程,會帶來什么問題,怎么解決,我只停留在概念上面,沒有深入,倍感慚愧。晚上回來google了一下,再次參考APUE,認(rèn)真總結(jié)一下,加深理解。

2、基本概念

  我們知道在unix/linux中,正常情況下,子進(jìn)程是通過父進(jìn)程創(chuàng)建的,子進(jìn)程在創(chuàng)建新的進(jìn)程。子進(jìn)程的結(jié)束和父進(jìn)程的運(yùn)行是一個異步過程,即父進(jìn)程永遠(yuǎn)無法預(yù)測子進(jìn)程 到底什么時候結(jié)束。 當(dāng)一個 進(jìn)程完成它的工作終止之后,它的父進(jìn)程需要調(diào)用wait()或者waitpid()系統(tǒng)調(diào)用取得子進(jìn)程的終止?fàn)顟B(tài)。

  孤兒進(jìn)程:一個父進(jìn)程退出,而它的一個或多個子進(jìn)程還在運(yùn)行,那么那些子進(jìn)程將成為孤兒進(jìn)程。孤兒進(jìn)程將被init進(jìn)程(進(jìn)程號為1)所收養(yǎng),并由init進(jìn)程對它們完成狀態(tài)收集工作。

  僵尸進(jìn)程:一個進(jìn)程使用fork創(chuàng)建子進(jìn)程,如果子進(jìn)程退出,而父進(jìn)程并沒有調(diào)用wait或waitpid獲取子進(jìn)程的狀態(tài)信息,那么子進(jìn)程的進(jìn)程描述符仍然保存在系統(tǒng)中。這種進(jìn)程稱之為僵死進(jìn)程。

3、問題及危害

  unix提供了一種機(jī)制可以保證只要父進(jìn)程想知道子進(jìn)程結(jié)束時的狀態(tài)信息, 就可以得到。這種機(jī)制就是: 在每個進(jìn)程退出的時候,內(nèi)核釋放該進(jìn)程所有的資源,包括打開的文件,占用的內(nèi)存等。 但是仍然為其保留一定的信息(包括進(jìn)程號the PRocess ID,退出狀態(tài)the termination status of the process,運(yùn)行時間the amount of CPU time taken by the process等)。直到父進(jìn)程通過wait / waitpid來取時才釋放。 但這樣就導(dǎo)致了問題,如果進(jìn)程不調(diào)用wait / waitpid的話, 那么保留的那段信息就不會釋放,其進(jìn)程號就會一直被占用,但是系統(tǒng)所能使用的進(jìn)程號是有限的,如果大量的產(chǎn)生僵死進(jìn)程,將因?yàn)闆]有可用的進(jìn)程號而導(dǎo)致系統(tǒng)不能產(chǎn)生新的進(jìn)程. 此即為僵尸進(jìn)程的危害,應(yīng)當(dāng)避免。

  孤兒進(jìn)程是沒有父進(jìn)程的進(jìn)程,孤兒進(jìn)程這個重任就落到了init進(jìn)程身上,init進(jìn)程就好像是一個民政局,專門負(fù)責(zé)處理孤兒進(jìn)程的善后工作。每當(dāng)出現(xiàn)一個孤兒進(jìn)程的時候,內(nèi)核就把孤 兒進(jìn)程的父進(jìn)程設(shè)置為init,而init進(jìn)程會循環(huán)地wait()它的已經(jīng)退出的子進(jìn)程。這樣,當(dāng)一個孤兒進(jìn)程凄涼地結(jié)束了其生命周期的時候,init進(jìn)程就會代表黨和政府出面處理它的一切善后工作。因此孤兒進(jìn)程并不會有什么危害。

  任何一個子進(jìn)程(init除外)在exit()之后,并非馬上就消失掉,而是留下一個稱為僵尸進(jìn)程(Zombie)的數(shù)據(jù)結(jié)構(gòu),等待父進(jìn)程處理。這是每個 子進(jìn)程在結(jié)束時都要經(jīng)過的階段。如果子進(jìn)程在exit()之后,父進(jìn)程沒有來得及處理,這時用ps命令就能看到子進(jìn)程的狀態(tài)是“Z”。如果父進(jìn)程能及時 處理,可能用ps命令就來不及看到子進(jìn)程的僵尸狀態(tài),但這并不等于子進(jìn)程不經(jīng)過僵尸狀態(tài)。  如果父進(jìn)程在子進(jìn)程結(jié)束之前退出,則子進(jìn)程將由init接管。init將會以父進(jìn)程的身份對僵尸狀態(tài)的子進(jìn)程進(jìn)行處理。

  僵尸進(jìn)程危害場景:

  例如有個進(jìn)程,它定期的產(chǎn) 生一個子進(jìn)程,這個子進(jìn)程需要做的事情很少,做完它該做的事情之后就退出了,因此這個子進(jìn)程的生命周期很短,但是,父進(jìn)程只管生成新的子進(jìn)程,至于子進(jìn)程 退出之后的事情,則一概不聞不問,這樣,系統(tǒng)運(yùn)行上一段時間之后,系統(tǒng)中就會存在很多的僵死進(jìn)程,倘若用ps命令查看的話,就會看到很多狀態(tài)為Z的進(jìn)程。 嚴(yán)格地來說,僵死進(jìn)程并不是問題的根源,罪魁禍?zhǔn)资钱a(chǎn)生出大量僵死進(jìn)程的那個父進(jìn)程。因此,當(dāng)我們尋求如何消滅系統(tǒng)中大量的僵死進(jìn)程時,答案就是把產(chǎn)生大 量僵死進(jìn)程的那個元兇槍斃掉(也就是通過kill發(fā)送SIGTERM或者SIGKILL信號啦)。槍斃了元兇進(jìn)程之后,它產(chǎn)生的僵死進(jìn)程就變成了孤兒進(jìn) 程,這些孤兒進(jìn)程會被init進(jìn)程接管,init進(jìn)程會wait()這些孤兒進(jìn)程,釋放它們占用的系統(tǒng)進(jìn)程表中的資源,這樣,這些已經(jīng)僵死的孤兒進(jìn)程 就能瞑目而去了。

3、孤兒進(jìn)程和僵尸進(jìn)程測試

孤兒進(jìn)程測試程序如下所示:

復(fù)制代碼
 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <errno.h> 4 #include <unistd.h> 5  6 int main() 7 { 8     pid_t pid; 9     //創(chuàng)建一個進(jìn)程10     pid = fork();11     //創(chuàng)建失敗12     if (pid < 0)13     {14         perror("fork error:");15         exit(1);16     }17     //子進(jìn)程18     if (pid == 0)19     {20         printf("I am the child process./n");21         //輸出進(jìn)程ID和父進(jìn)程ID22         printf("pid: %d/tppid:%d/n",getpid(),getppid());23         printf("I will sleep five seconds./n");24         //睡眠5s,保證父進(jìn)程先退出25         sleep(5);26         printf("pid: %d/tppid:%d/n",getpid(),getppid());27         printf("child process is exited./n");28     }29     //父進(jìn)程30     else31     {32         printf("I am father process./n");33         //父進(jìn)程睡眠1s,保證子進(jìn)程輸出進(jìn)程id34         sleep(1);35         printf("father process is  exited./n");36     }37     return 0;38 }復(fù)制代碼

測試結(jié)果如下:

僵尸進(jìn)程測試程序如下所示:

復(fù)制代碼
 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <errno.h> 4 #include <stdlib.h> 5  6 int main() 7 { 8     pid_t pid; 9     pid = fork();10     if (pid < 0)11     {12         perror("fork error:");13         exit(1);14     }15     else if (pid == 0)16     {17         printf("I am child process.I am exiting./n");18         exit(0);19     }20     printf("I am father process.I will sleep two seconds/n");21     //等待子進(jìn)程先退出22     sleep(2);23     //輸出進(jìn)程信息24     system("ps -o pid,ppid,state,tty,command");25     printf("father process is exiting./n");26     return 0;27 }復(fù)制代碼

測試結(jié)果如下所示:

僵尸進(jìn)程測試2:父進(jìn)程循環(huán)創(chuàng)建子進(jìn)程,子進(jìn)程退出,造成多個僵尸進(jìn)程,程序如下所示:

復(fù)制代碼
 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5  6 int main() 7 { 8     pid_t  pid; 9     //循環(huán)創(chuàng)建子進(jìn)程10     while(1)11     {12         pid = fork();13         if (pid < 0)14         {15             perror("fork error:");16             exit(1);17         }18         else if (pid == 0)19         {20             printf("I am a child process./nI am exiting./n");21             //子進(jìn)程退出,成為僵尸進(jìn)程22             exit(0);23         }24         else25         {26             //父進(jìn)程休眠20s繼續(xù)創(chuàng)建子進(jìn)程27             sleep(20);28             continue;29         }30     }31     return 0;32 }復(fù)制代碼

程序測試結(jié)果如下所示:

4、僵尸進(jìn)程解決辦法

(1)通過信號機(jī)制

  子進(jìn)程退出時向父進(jìn)程發(fā)送SIGCHILD信號,父進(jìn)程處理SIGCHILD信號。在信號處理函數(shù)中調(diào)用wait進(jìn)行處理僵尸進(jìn)程。測試程序如下所示:

復(fù)制代碼
 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <errno.h> 4 #include <stdlib.h> 5 #include <signal.h> 6  7 static void sig_child(int signo); 8  9 int main()10 {11     pid_t pid;12     //創(chuàng)建捕捉子進(jìn)程退出信號13     signal(SIGCHLD,sig_child);14     pid = fork();15     if (pid < 0)16     {17         perror("fork error:");18         exit(1);19     }20     else if (pid == 0)21     {22         printf("I am child process,pid id %d.I am exiting./n",getpid());23         exit(0);24     }25     printf("I am father process.I will sleep two seconds/n");26     //等待子進(jìn)程先退出27     sleep(2);28     //輸出進(jìn)程信息29     system("ps -o pid,ppid,state,tty,command");30     printf("father process is exiting./n");31     return 0;32 }33 34 static void sig_child(int signo)35 {36      pid_t        pid;37      int        stat;38      //處理僵尸進(jìn)程39      while ((pid = waitpid(-1, &stat, WNOHANG)) >0)40             printf("child %d terminated./n", pid);41 }復(fù)制代碼

測試結(jié)果如下所示:

(2)fork兩次  《Unix 環(huán)境高級編程》8.6節(jié)說的非常詳細(xì)。原理是將子進(jìn)程成為孤兒進(jìn)程,從而其的父進(jìn)程變?yōu)閕nit進(jìn)程,通過init進(jìn)程可以處理僵尸進(jìn)程。測試程序如下所示:

復(fù)制代碼
 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5  6 int main() 7 { 8     pid_t  pid; 9     //創(chuàng)建第一個子進(jìn)程10     pid = fork();11     if (pid < 0)12     {13         perror("fork error:");14         exit(1);15     }16     //第一個子進(jìn)程17     else if (pid == 0)18     {19         //子進(jìn)程再創(chuàng)建子進(jìn)程20         printf("I am the first child process.pid:%d/tppid:%d/n",getpid(),getppid());21         pid = fork();22         if (pid < 0)23         {24             perror("fork error:");25             exit(1);26         }27         //第一個子進(jìn)程退出28         else if (pid >0)29         {30             printf("first procee is exited./n");31             exit(0);32         }33         //第二個子進(jìn)程34         //睡眠3s保證第一個子進(jìn)程退出,這樣第二個子進(jìn)程的父親就是init進(jìn)程里35         sleep(3);36         printf("I am the second child process.pid: %d/tppid:%d/n",getpid(),getppid());37         exit(0);38     }39     //父進(jìn)程處理第一個子進(jìn)程退出40     if (waitpid(pid, NULL, 0) != pid)41     {42         perror("waitepid error:");43         exit(1);44     }45     exit(0);46     return 0;47 }復(fù)制代碼

測試結(jié)果如下圖所示:

5、參考資料

《unix環(huán)境高級編程》第八章

http://www.rosoo.net/a/201109/15071.html

http://blog.chinaunix.net/uid-1829236-id-3166986.html

http://forkhope.diandian.com/post/2012-10-01/40040574200

http://blog.csdn.net/metasearch/article/details/2498853

http://blog.csdn.net/yuwenliang/article/details/6770750

冷靜思考,勇敢面對,把握未來!
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本高清视频网站 | 久久久久久久久久久网站 | 日韩中文一区二区三区 | 91精品国产综合久久久久久丝袜 | 亚洲一二三四五六区 | 午夜激情在线 | 欧美一区在线视频 | 国产精品久久久久久吹潮 | 日韩在线免费视频 | 亚洲福利小视频 | 欧美成人在线免费视频 | 日韩在线播放视频 | 在线免费观看成人 | 国产91精品一区二区绿帽 | 在线视频91| 亚洲精品国品乱码久久久久 | 国产精品视频免费看 | 国产精品国产 | av大片在线免费观看 | 98精品国产高清在线xxxx天堂 | 久久精品99国产精品亚洲最刺激 | 亚洲人成中文字幕在线观看 | 中国一级特黄毛片大片 | 日日夜夜狠狠 | 99视频精品 | 国产91色在线 | 亚洲 | 99视频网站 | 国产精品亚洲一区二区三区在线 | 天天干视频 | 日韩一区二区电影 | 精品国产一区二区三区久久久 | 一区二区三区四区视频 | 日本久久精品一区 | 日本免费在线观看 | 成人国产精品久久 | 国产高清中文字幕 | 四虎精品成人免费网站 | 欧美一区二区免费 | 亚洲h视频在线观看 | 91在线资源| 免费黄色的视频 |