進程—殭屍進程與孤兒進程

原博客地址http://blog.csdn.net/l953972252/article/details/51399576

在探討這個問題之前,我們先來弄清什麼是進程。
進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。
進程是一個具有獨立功能的程序關於某個數據集合的一次運行活動。它可以申請和擁有系統資源,是一個動態的概念,是一個活動的實體。它不只是程序的代碼,還包括當前的活動,通過程序計數器的值和處理寄存器的內容來表示。 ——360百科

通俗點講,進程是一段程序的執行過程,是個動態概念

一、狀態分類
進程在之前分爲3個狀態:
1. 運行狀態(Running):正在CPU中運行的進程。
2. 就緒狀態(Ready):已獲得除了處理器外的所需資源,隨時準備着運行的進程。
3. 阻塞狀態(Blocked) 因爲缺少除了CPU外的其他資源,無法滿足運行條件的進程。

後來人們發現3個狀態無法滿足需求,特意加了就緒掛起狀態,和阻塞掛起狀態。
程序運行必須加載在內存中,當有過多的就緒阻塞進程在內存中沒有運行(佔着茅坑不拉屎),內存很小,可能不足。系統需要把他們移動到內存外磁盤中,稱爲掛起狀態。就緒狀態的進程掛起就是掛起就緒狀態,阻塞進程掛起就稱爲阻塞掛起狀態。

每個進程的產生都有自己的唯一的ID號,並且附帶有一個它父進程的PID號。進程死亡時,ID被回收。一個系統一般只能同時運行幾百的進程。

進程間靠優先級獲得CPU資源,時間片段輪換來更新優先級,以保證不會一個進程佔據CPU時間過長。每個進程都得到輪換運行,就好像是系統在同時運行好多進程。

二、殭屍進程
 殭屍進程:一個進程使用fork創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之爲僵死進程。
一個進程在調用exit命令結束自己的生命的時候,其實它並沒有真正的被銷燬,而是留下一個稱爲殭屍進程(Zombie)的數據結構(系統調用exit,它的作用是使進程退出,但也僅僅限於將一個正常的進程變成一個殭屍進程,並不能將其完全銷燬)。在Linux進程的狀態中,殭屍進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,殭屍進程不再佔有任何內存空間。它需要它的父進程來爲它收屍,如果他的父進程沒安裝SIGCHLD信號處理函數調用wait或waitpid()等待子進程結束,又沒有顯式忽略該信號,那麼它就一直保持殭屍狀態,如果這時父進程結束了,那麼init進程自動會接手這個子進程,爲它收屍,它還是能被清除的。但是如果如果父進程是一個循環,不會結束,那麼子進程就會一直保持殭屍狀態,這就是爲什麼系統中有時會有很多的殭屍進程。

值得注意的是:
所有的進程都會有成爲殭屍進程的過程,每個進程在終結時都會將自己進程的信息發給父進程,等待父進程來處理,這個等待階段就是殭屍進程。不同的是,一般的父進程會很快將已經死亡的子進程處理掉,但是父進程沒有收到信息,或者陷入死循環不能處理時,這個殭屍進程就永遠的掛在系統中,無法處理了。殭屍進程佔用一個進程ID號,但沒辦法釋放,這無疑對系統是種危害。

三、孤兒進程
  孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那麼那些子進程將成爲孤兒進程。孤兒進程將被init進程(進程號爲1)所收養,並由init進程對它們完成狀態收集工作。

子進程死亡需要父進程來處理,那麼意味着正常的進程應該是子進程先於父進程死亡。當父進程先於子進程死亡時,子進程死亡時沒父進程處理,這個死亡的子進程就是孤兒進程。

但孤兒進程與殭屍進程不同的是,由於父進程已經死亡,系統會幫助父進程回收處理孤兒進程。所以孤兒進程實際上是不佔用資源的,因爲它終究是被系統回收了。不會像殭屍進程那樣佔用ID,損害運行系統。

四、殭屍進程的處理
得出結論,孤兒進程不會佔資源,殭屍進程會佔用資源危害系統。我們應當避免殭屍進程的出現。
解決辦法如下:
1)通過信號機制
  子進程退出時向父進程發送SIGCHILD信號,父進程處理SIGCHILD信號。調用wait()或者waitpid(),讓父進程阻塞等待殭屍進程的出現,處理完在繼續運行父進程。
2)殺死父進程
當父進程陷入死循環等無法處理殭屍進程時,強制殺死父進程,那麼它的子進程,即殭屍進程會變成孤兒進程,由系統來回收。
3)重啓系統
當系統重啓時,所有進程在系統關閉時被停止,包括殭屍進程,開啓時init進程會重新加載其他進程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章