Linux複習篇(五) 僵死程序和孤兒程序

2021-09-25 18:24:31 字數 1580 閱讀 4497

概念:乙個父程序利用fork建立子程序,如果子程序先於父程序退出,而父程序收到核心發來的sigchld訊號,並沒有利用wait 或者  waitpid 來發出進行適當處理獲取子程序的狀態資訊(退出碼),**子程序,那麼子程序的狀態描述符依然儲存在系統中,等待父程序收屍。

危害:在linux程序的狀態中,殭屍程序是非常特殊的一種,它已經放棄了幾乎所有記憶體空間,沒有任何可執行**,也不能被排程,僅僅在程序列表中保留乙個位置,記載該程序的退出狀態等資訊供其他程序收集,除此之外,殭屍程序不再占有任何記憶體空間。這個殭屍程序需要它的父程序來為它收屍,如果他的父程序沒有處理這個殭屍程序的措施,那麼它就一直保持殭屍狀態,如果這時父程序結束了,那麼init程序自動會接手這個子程序,為它收屍,它還是能被清除的。但是如果如果父程序是乙個迴圈(或者是乙個伺服器程式),不會結束,那麼子程序就會一直保持殭屍狀態,這就是為什麼系統中有時會有很多的殭屍程序。(占有pid,pid是有限的)

試想一下,如果有大量的殭屍程序駐在系統之中,必然消耗大量的系統資源。但是系統資源是有限的,因此當殭屍程序達到一定數目時,系統因缺乏資源而導致奔潰。所以在實際程式設計中,避免和防範殭屍程序的產生顯得尤為重要。 

解決辦法:1):一種比較暴力的做法是將其父程序殺死,那麼它的子程序,即殭屍程序會變成孤兒程序,由系統(init程序)來**。但是這種做法在大多數情況下都是不可取的,如父程序是乙個伺服器程式,如果為了**其子程序的資源,而殺死伺服器程式,那麼將導致整個伺服器崩潰,得不償失。顯然這種**程序的方式是不可取的,但其也有一定的存在意義。

2):sigchld訊號處理

我們都知道wait函式是用來處理殭屍程序的,但是程序一旦呼叫了wait,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣乙個已經變成殭屍的子程序,wait就會收集這個子程序的資訊,並把它徹底銷毀後返回;如果沒有找到這樣乙個子程序,wait就會一直阻塞在這裡,直到有乙個出現為止。

由於呼叫wait之後,就必須阻塞,直到有子程序結束,所以,這樣來說是非常不高效的。那是怎麼處理的呢?實際上當子程序終止時,核心就會向它的父程序傳送乙個sigchld訊號,父程序可以選擇忽略該訊號,也可以提供乙個接收到訊號以後的處理函式。對於這種訊號的系統預設動作是忽略它。我們不希望有過多的殭屍程序產生,所以當父程序接收到sigchld訊號後就應該呼叫 wait 或 waitpid 函式對子程序進行善後處理,釋放子程序占用的資源。

概念:父程序先於子程序退出,而它的乙個或多個子程序還在執行,那麼那些子程序將成為孤兒程序。孤兒程序將被init程序(程序號為1)所收養,並由init程序對它們完成狀態收集工作。

孤兒程序與殭屍程序不同的是,由於父程序已經死亡,系統會幫助父程序**處理孤兒程序。所以孤兒程序實際上是不占用資源的,因為它終究是被系統**了。不會像殭屍程序那樣占用pid,損害執行系統。

linux 中的僵死程序和孤兒程序

當我們使用建立程序的函式fork vfork 等,建立了子程序 1.子程序先於父親程序退出,會造成子程序的程序編號無法釋放.程序編號的範圍很大,但不應該隨意浪費 2.子程序後於父親程序退出,子程序會交給init 程序管理.3.乙個程序在執行完畢後,系統會自動清空其存在的程序的相關資源 結合上面說明,...

僵死程序和孤兒程序的產生和處理

1 僵死程序的產生 子程序先於父程序結束,這是需要父程序最子程序的pcb進行釋放,如果父程序沒有對已經結束的子程序進行pcb釋放,那麼該子程序就一直處於僵死狀態,如果父程序執行一段時間也結束了,那還好辦,init程序會接收這個僵死的子程序對其pcb進行釋放,但是如果父程序一直迴圈,那麼子程序就一直處...

linux環境程式設計 孤兒程序,殭屍程序,守護程序

前面的 程序控制我們已經陸續的介紹啦,今天介紹一下孤兒程序,殭屍程序,還有守護程序 一.孤兒程序 父程序 先於 子程序結束,那子程序就成為了孤兒程序,父程序的資源被 init程序 沒有結束的子程序就被init程序領養,init程序可以被看程是孤兒院的院長。二.殭屍程序 父程序 還在執行 子程序已經結...