以下部分引用自
首先說明,每個程序退出的時候,核心釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。 但是仍然為其保留一定的資訊(包括程序號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卻有辦法捕捉到,以下是**:
子程序建立完畢,父程序接著執行print
4print
"fffffffffffffffffffffffffffffff
"5 time.sleep(40)#
父程序活了40秒,而子程序10秒就死了,在子程序死亡以後父程序未死亡之前,父程序並沒有給子程序送終,而是幹自己的事情。這個階段子程序就是殭屍狀態。
如果把以上**popen換成call,則就捕捉不到子程序變為殭屍狀態的瞬間了,因為父程序等待子程序死亡並給其送終後,才執行print。
假如,以上**,父程序長生不老,並且一直在製造子程序,並且主要是製造了子程序以後還不為他送終(),那麼隨著子程序乙個個的成為殭屍程序,保留的那段資訊就不會釋放,其程序號就會一直被占用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序. 這是有害的,所以要避免這種情況的發生。
而事實上上述**,父程序存活了40多秒,父程序死亡後,被其自己的父程序送終,而其子程序(注意此時其子程序屬殭屍態)則由init程序接管,init程序馬上給他送終
那什麼是孤兒程序呢?把以上**,time.sleep(40)去掉,也就是說讓父程序早於子程序死亡,那麼此時的子程序就是孤兒程序了,但是他隨即就會被過季給init程序(此時用ps命令可檢視到這個子程序的ppid已經變為1了),由init來盡其生父未盡之事,因此孤兒程序並不會有什麼危害
糾正一點,子程序的退出碼是返回給系統的,並不是返回給父程序的,父程序通過wait呼叫,才能得到此退出碼
說一下通過popen建立的子程序,父程序如何為其送終
子程序建立完畢,父程序接著執行print
"fffffffffffffffffffffffffffffff
"time.sleep(40)
child.wait()
#這就是送終
簡而言之,父程序以死,子程序還在執行,這個子程序就是孤兒程序。父進城還活著,子程序已經結束執行,父進城沒有給紫禁城收屍就是殭屍進城
kill -9 pid是殺不死殭屍進城的,他能將進城的狀態從正在執行態變成殭屍態,卻不能將殭屍態變為消亡。要想殺死殭屍態,只能kill -9 ppid(此ppid指的是殭屍進城的附近成)
殭屍程序與孤兒程序
殭屍程序 如果乙個程序通過fork 建立子了乙個程序,當子程序退出而父程序還沒有呼叫wait waitpid來儲存子程序的狀態且 它,此時子程序的狀態描述資訊仍然保留在系統中,稱這類程序為殭屍程序 殭屍程序的優點是方便上層程序得知子程序的退出狀態,但是如果不及時 會造成記憶體洩露 孤兒程序 當乙個父...
殭屍程序與孤兒程序
孤兒程序是指在程序還未退出之前它的父程序就已經先退出了,簡單來說就是乙個沒有父程序的子程序就是孤兒程序。既然所有的程序都必須在退出之後被父程序的wait 或waitpid 以釋放其遺留在系統中的一些資源,那麼孤兒程序的這些東西又誰來處理呢?這個任務就落到了init程序的身上,init程序就好像乙個收...
殭屍程序與孤兒程序
在父程序執行wait 之前,其子程序就已終止,即使子程序終止,系統也允許父程序在以後的某個時刻去執行wait 以確定子程序是如何終止。核心通過將子程序轉為殭屍程序,以釋放其占用的系統資源,供其他程序使用,該程序唯一保留的是系統pcb中的一條記錄,其中包含了子程序的id,終止狀態,和資源使用的資料。當...