1. 程式人生 > >孤兒進程與僵屍進程

孤兒進程與僵屍進程

信息 進程創建 代碼 www. 進程id pytho 通過 了解 等待

以下部分引用自https://www.cnblogs.com/Anker/p/3271773.html

首先說明,每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等。 但是仍然為其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放(給子進程送終)。釋放完了這個子進程就徹底消失了,用ps命令也查不到了。

而在子進程退出,內核釋放了子進程所有的資源以後,父進程沒有通過wait/waitid來獲取並釋放之前,這個進程的狀態就是僵屍狀態(Z狀態),所以說,僵屍狀態是每個進程都會經歷的過程。

為了說明問題,先要了解,subprocess包是python創建子進程的包,其中有兩個方法,一個是call,一個是Popen,二者的區別是,調用call方法的父進程,會等待子進程執行完畢並給其送終(父進程調用wait來獲取並釋放子進程id),然後才接著執行,而popen則不同,父進程創建了子進程後,就接著執行自己的代碼了。所以,調用call我們捕捉不到子進程變為僵屍進程的短暫瞬間,而popen卻有辦法捕捉到,以下是代碼:

1 import time
2 import subprocess
3 child = subprocess.Popen(["ping","-c","10","www.baidu.com
"])#子進程創建完畢,父進程接著執行print 4 print "fffffffffffffffffffffffffffffff" 5 time.sleep(40)#父進程活了40秒,而子進程10秒就死了,在子進程死亡以後父進程未死亡之前,父進程並沒有給子進程送終,而是幹自己的事情。這個階段子進程就是僵屍狀態。

如果把以上代碼popen換成call,則就捕捉不到子進程變為僵屍狀態的瞬間了,因為父進程等待子進程死亡並給其送終後,才執行print。

假如,以上代碼,父進程長生不老,並且一直在制造子進程,那麽隨著子進程一個個的成為僵屍進程,保留的那段信息就不會釋放,其進程號就會一直被占用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 這是有害的,所以要避免這種情況的發生。

那什麽是孤兒進程呢?把以上代碼,time.sleep(40)去掉,也就是說讓父進程早於子進程死亡,那麽此時的子進程就是孤兒進程了,但是他隨即就會被過季給init進程(此時用ps命令可查看到這個子進程的ppid已經變為1了),由init來盡其生父未盡之事,因此孤兒進程並不會有什麽危害

孤兒進程與僵屍進程