python僵尸进程和孤儿进程_python学习笔记——孤儿进程和僵尸进程
1 基本概述
1.1 孤兒進程和僵尸進程
父進程創建子進程后,較為理想狀態是子進程結束,父進程回收子進程并釋放子進程占有的資源;而實際上,父子進程是異步過程,兩者誰先結束是無順的,一般可以通過父進程調用wait()或waitpid()語句來等待子進程結束再退出。
孤兒進程:父進程結束后還有基于該父進程創建的子進程(一個或多個)尚沒有結束,此時的子進程稱之為孤兒進程;孤兒進程將被init進程(進程樹中除了init都有父進程)接受,也就意味著init進程負責孤兒進程完成狀態收集工作。一般而言,init進程的pid為1,有資料顯示init有三種形式,其pid并不為1。
僵尸進程:在Linux進程狀態及轉換關系中有一種進程狀態是僵尸狀態(zombie),此時該進程稱之為僵尸進程;當使用fork創建子進程后,子進程退出,而父進程并沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程中的進程描述仍然保存在系統中,這種進程稱之為僵尸進程,有時也稱為僵死進程。
1.2 孤兒進程和僵尸進程危害
孤兒進程:孤兒進程不會占用系統資源,系統會將父進程回收處理孤兒進程,所以孤兒進程不占用系統資源;有時還會利用孤兒進程的這一原理進程程序邏輯設計。
僵尸進程:Lunix提供了父進程獲取子進程狀態信息的機制;在每一個進程退出的時候,內核會釋放該進程所有的資源,包括打開的文件、占用的內存等;但是仍然為其保留一定的信息(這些信息涵蓋有進程號the process ID、退出狀態the termination status of the process、運行時間the amount of CPU time taken by the process等),直到父進程調用wait() / waitpid()時才釋放,
一個進程在調用exit命令結束自己的生命的時候,其實它并沒有真正的被銷毀,而是留下一個稱為僵尸進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限于將一個正常的進程變成一個僵尸進程,并不能將其完全銷毀)。在Linux進程的狀態中,僵尸進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。它需要它的父進程來為它收尸,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那么它就一直保持僵尸狀態,如果這時父進程結束了,那么init進程自動會接手這個子進程,為它收尸,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那么子進程就會一直保持僵尸狀態,這就是為什么系統中有時會有很多的僵尸進程。
值得注意的是:
所有的進程都會有成為僵尸進程的過程,每個進程在終結時都會將自己進程的信息發給父進程,等待父進程來處理,這個等待階段就是僵尸進程。不同的是,一般的父進程會很快將已經死亡的子進程處理掉,但是父進程沒有收到信息,或者陷入死循環不能處理時,這個僵尸進程就永遠的掛在系統中,無法處理了。僵尸進程占用一個進程ID號,但沒辦法釋放,這無疑對系統是種危害。
unix提供了一種機制可以保證只要父進程想知道子進程結束時的狀態信息, 就可以得到。這種機制就是: 在每個進程退出的時候,內核釋放該進程所有的資源,包括打開的文件,占用的內存等。 但是仍然為其保留一定的信息(包括進程號the process ID,退出狀態the termination status of the process,運行時間the amount of CPU time taken by the process等)。直到父進程通過wait / waitpid來取時才釋放。 但這樣就導致了問題,如果進程不調用wait / waitpid的話, 那么保留的那段信息就不會釋放,其進程號就會一直被占用,但是系統所能使用的進程號是有限的,如果大量的產生僵死進程,將因為沒有可用的進程號而導致系統不能產生新的進程. 此即為僵尸進程的危害,應當避免。
但孤兒進程與僵尸進程不同的是,由于父進程已經死亡,系統會幫助父進程回收處理孤兒進程。所以孤兒進程實際上是不占用資源的,因為它終究是被系統回收了。不會像僵尸進程那樣占用ID,損害運行系統。
孤兒進程結束后會被 init 進程善后,并沒有危害,而僵尸進程則會一直占著進程號,操作系統的進程數量有限則會受影響。
一個進程使用fork創建子進程,如果子進程退出,而父進程并沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中。這種進程稱之為僵死進程。
如果我們了解過linux進程狀態及轉換關系,我們應該知道進程這么多狀態中有一種狀態是僵死狀態,就是進程終止后進入僵死狀態,等待告知父進程自己終止,后才能完全消失.但是如果一個進程已經終止了,但是其父進程還沒有獲取其狀態,那么這個進程就稱之為僵尸進程.僵尸進程還會消耗一定的系統資源,并且還保留一些概要信息供父進程查詢子進程的狀態可以提供父進程想要的信息.一旦父進程得到想要的信息,僵尸進程就會結束.
1、一般情況下,子進程是由父進程創建,而子進程和父進程的退出是無順序的,兩者之間都不知道誰先退出。正常情況下父進程先結束會調用 wait 或者 waitpid 函數等待子進程完成再退出,而一旦父進程不等待直接退出,則剩下的子進程會被init(pid=1)進程接收,成會孤兒進程。(進程樹中除了init都會有父進程)。
2、如果子進程先退出了,父進程還未結束并且沒有調用 wait 或者 waitpid 函數獲取子進程的狀態信息,則子進程殘留的狀態信息( task_struct 結構和少量資源信息)會變成僵尸進程。
子進程死亡需要父進程來處理,那么意味著正常的進程應該是子進程先于父進程死亡。當父進程先于子進程死亡時,子進程死亡時沒父進程處理,這個死亡的子進程就是孤兒進程。
但孤兒進程與僵尸進程不同的是,由于父進程已經死亡,系統會幫助父進程回收處理孤兒進程。所以孤兒進程實際上是不占用資源的,因為它終究是被系統回收了。不會像僵尸進程那樣占用ID,損害運行系統。
父進程是調用wait()或waitpid()系統調用獲得的子進程的終止狀態。
當子進程比父進程先結束,而父進程又沒有回收子進程,釋放子進程占用的資源,此時子進程將成為一個僵尸進程。如果父進程先退出
,子進程被init接管,子進程退出后init會回收其占用的相關資源。
總結
以上是生活随笔為你收集整理的python僵尸进程和孤儿进程_python学习笔记——孤儿进程和僵尸进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 目录后面的空白页删不掉怎么办(Word文
- 下一篇: wps云空间怎样批量删除?