今天在書上看到了 “僵屍進程與孤兒進程”的描述,又查看了一些資料,對這兩種進程又多了點認識,這裡簡要記錄下。 這兩種進程粗看好像是差不多的,因為都有可能會被init進程回收,但是總的來說還是有點不一樣,不管從產生的方式和危害程式都是不一樣的。 僵屍進程與孤兒進程的產生 僵屍進程:子進程先結束,然後父 ...
今天在書上看到了 “僵屍進程與孤兒進程”的描述,又查看了一些資料,對這兩種進程又多了點認識,這裡簡要記錄下。
這兩種進程粗看好像是差不多的,因為都有可能會被init進程回收,但是總的來說還是有點不一樣,不管從產生的方式和危害程式都是不一樣的。
僵屍進程與孤兒進程的產生
僵屍進程:子進程先結束,然後父進程又不管他,init進程來管理回收。
孤兒進程:父進程先結束,子進程找不到父了,init進程來回收。
僵屍進程回收:把父進程殺死,然後就由init回收了。
所以,僵屍進程與孤兒進程的產生就看是父進程還是子進程先結束。
僵屍進程
子進程結束時,父進程沒有對子進程進行等待,不管他的死活。如果程式中父進程能正常結束還好,因為一旦子進程找不到它的父的話,會由init進程接管進行回收處理。
最悲劇的是,一般父進程都是掛一個迴圈在那裡,不會結束的,這個時候系統發現你的父進程還存在的,然後init就不會管你,就產生僵屍進程了,而且如果產生太多會浪費大量的系統資源。
僵屍進程也不能用kill殺死,因為他的進程已經死了。
以下程式會產生僵屍進程,父進程沒有等待子進程。通過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接管回收了。
以下程式父進程先結束,子進程延時一下,然後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等來等待子進程的結束,從而回收資源。