今天在書上看到了 「殭屍進程與孤兒進程」的描述,又查看了一些資料,對這兩種進程又多了點認識,這裏簡要記錄下。
這兩種進程粗看好像是差很少的,由於都有可能會被init進程回收,可是總的來講仍是有點不同,無論從產生的方式和危害程序都是不同的。php
殭屍進程:子進程先結束,而後父進程又無論他,init進程來管理回收。
孤兒進程:父進程先結束,子進程找不到父了,init進程來回收。
殭屍進程回收:把父進程殺死,而後就由init回收了。code
因此,殭屍進程與孤兒進程的產生就看是父進程仍是子進程先結束。進程
子進程結束時,父進程沒有對子進程進行等待,無論他的死活。若是程序中父進程能正常結束還好,由於一旦子進程找不到它的父的話,會由init進程接管進行回收處理。資源
最悲劇的是,通常父進程都是掛一個循環在那裏,不會結束的,這個時候系統發現你的父進程還存在的,而後init就不會管你,就產生殭屍進程了,並且若是產生太多會浪費大量的系統資源。get
殭屍進程也不能用kill殺死,由於他的進程已經死了。it
如下程序會產生殭屍進程,父進程沒有等待子進程。經過ps -ef中,能看到
<?php $pid = pcntl_fork(); if ($pid == -1) { die('fork error'); } else if ($pid > 0) { echo "I'm parent" .PHP_EOL; while(true){ sleep(3); } } else { echo "I'm child".PHP_EOL; }
顧名思義就是進程成孤兒了,由於它的父進程先結束了,它產生的子進程就懵逼了,找不到它的父了,這個時候就只能被init接管回收了。class
如下程序父進程先結束,子進程延時一下,而後posix_getppid()會返回1,表示被init接管了循環
<?php $pid = pcntl_fork(); if ($pid == -1) { die('fork error'); } else if ($pid > 0) { echo "I'm parent" .PHP_EOL; sleep(1); } else { echo "I'm child,ppid:".posix_getppid().PHP_EOL; sleep(3); echo "I'm child,ppid:" .posix_getppid().PHP_EOL; }
孤兒進程它會被init最終回收掉,因此危害相對來講要小不少,可是殭屍進程由於會佔用大量的進程號和系統資源,若是父進程一直不結束,那麼init進程也接管不了,這樣就會一直消耗資源源,因此危害相對要高一些。程序
編寫多進程程序時,父進程仍是須要使用wait,waitpid等來等待子進程的結束,從而回收資源。