模擬實現殭屍程序, 孤兒程序

2021-08-17 04:25:19 字數 3203 閱讀 2278

在linux下程序有多種狀態以下就是我列舉的一些狀態:

r執行狀態(running):並不意味著程序一定在執行中,它表明程序要麼在執行中要麼在執行佇列裡。

s睡眠狀態(sleeping):意味著程序在等待事件的完成(這裡的睡眠有時候也會叫可中斷睡眠)(interruptible sleep)。

d磁碟休眠狀態(disk sleep):有時候也叫做不可中斷睡眠(uninterruptible sleep),在這個狀態的程序通常會等待io的結束。

t停止狀態(stopped):可以通過傳送sigstop訊號給程序來停止(t)程序。這個被暫停的程序可以通過傳送sigcont訊號讓程序繼續執行。

x死亡狀態(dead):這個狀態只是乙個返回狀態,你不會在任務列表中看到這個狀態。

殭屍狀態

殭屍狀態是乙個比較特殊的狀態,當程序退出並且父程序沒有讀取到子程序退出的返回**時就會產生殭屍狀態。殭屍程序會以終止狀態保持在程序表中,並且會一直在等待父程序讀取退出狀態**,所以只要子程序退出,父程序沒有讀取子程序的狀態,子程序進入了z狀態。

問題一:為什麼程序會有殭屍狀態?

unix提供了一種機制可以保證只要父程序想知道子程序結束時的狀態資訊, 就可以得到。這種機制就是: 在每個程序退出的時候,核心釋放該程序所有的資源,包括開啟的檔案,占用的記憶體等。但是仍然為其保留一定的資訊(包括程序號the process id,退出狀態the termination status of the process,執行時間the amount of cpu time taken by the process等)。直到父程序通過wait / waitpid來取時才釋放。 這個存在是十分有意義的,可以接受,因為我們需要了解自己建立的程序的運**況,這樣才可控,失控(《失控》這本書也不錯)是很可怕的事兒,尤其是計算機;

問題二:為什麼要盡量避免殭屍程序?

因為系統中的程序數量是有限的,雖然殭屍程序占用的資源和記憶體都比較少,但是它卻占領著數字,可能會導致系統無法再建立新的程序,所以必須先清除殭屍程序。

問題三:如何避免殭屍程序?

(1)、父程序呼叫wait和waitpid來等待子程序的結束,但是這將

導致父程序的掛起,浪費資源

;(2)、如果父程序很忙,則可以通

過signal函式為sigchld來安裝handler

,因為子程序結束後一定會向父程序傳送乙個訊息訊號,這樣可以在handler裡呼叫wait來接收;

(3)、如果父程序不關心子程序的狀態,

可以用signal(sigchle,sigign)來通知核心

,告訴核心我對子程序沒興趣,你幫我**,那麼子程序結束後,就不會向父程序傳送訊號訊息,直接被核心**;

(4)、還有就

是fork()兩次

,這樣讓子程序直接退出,孫程序結束後就成了孤兒程序,會被init接管,直接**,不用祖父程序管了;

問題四:殭屍狀態是每個子程序比經過的狀態嗎?

任何乙個子程序(init除外)在exit()之後,並非馬上就消失掉,而是留下乙個稱為殭屍程序(zombie)的資料結構(它占用一點記憶體 資源,也就是程序表裡還有乙個記錄),等待父程序處理。這是每個子程序在結束時都要經過的階段。如果子程序在exit()之後,父程序沒有來得及處理,

這 時用ps命令就能看到子程序的狀態是「z」。

如果父程序能及時處理,可能用ps命令就來不及看到子程序的殭屍狀態,但這並不等於子程序不經過殭屍狀態。如果父程序在子程序結束之前退出,則子程序將由init接管。init將會以父程序的身份對殭屍狀態的子程序進行處理。所以不一定說每個程序一定是殭屍程序,但是如果子程序先結束,那麼殭屍程序就是它們的必經之途!

殭屍程序危害場景:「擒賊先擒王」

例如有個程序,它定期的產 生乙個子程序,這個子程序需要做的事情很少,做完它該做的事情之後就退出了,因此這個子程序的生命週期很短,但是,父程序只管生成新的子程序,至於子程序 退出之後的事情,則一概不聞不問,這樣,系統執行上一段時間之後,系統中就會存在很多的僵死程序,倘若用ps命令檢視的話,就會看到很多狀態為z的程序。 嚴格地來說,僵死程序並不是問題的根源,罪魁禍首是產生出大量僵死程序的那個父程序。因此,當我們尋求如何消滅系統中大量的僵死程序時,答案就是把產生大 量僵死程序的那個元凶槍斃掉(也就是通過kill傳送sigterm或者sigkill訊號啦)。槍斃了元凶程序(父程序)之後,它產生的僵死程序就變成了孤兒進 程,這些孤兒程序會被init程序接管,init程序會wait()這些孤兒程序,釋放它們占用的系統程序表中的資源,這樣,這些已經僵死的孤兒程序 就能瞑目而去了。

這就是守護程序的作用,如果發生大量的殭屍程序,守護程序就會查詢其父程序,然後無情的kill掉!

我們接下來就來建立乙個殭屍程序:

#include 2 #include 1 #include 2 #include
3 int main ()

4 10 else if(id>0)else is begin z....\n",getpid());

15 sleep(5);

16 exit(exit_success); //程序退出函式;exit_sucess是乙個巨集,表明程序執行成功

17 }

18 return 0;

19 20 }

執行的結果如下:

孤兒程序

顧名思義和我們顯示中所說的孤兒有點類似,當乙個程序的父程序結束時,但它自己還沒有結束,那麼這個程序將成為孤兒程序,最後孤兒程序會被init程序(init程序的pid為1)的程序收養,當然在子程序結束時也會有init程序完成對它的狀態的收集工作,因此一般來說,孤兒程序並沒有什麼危害。

建立的思路:在main函式中建立子程序,然後讓父程序睡眠1s,讓子程序先執行列印出其程序id(pid)以及父程序id(pid),隨後子程序睡眠5s(此時會排程到父程序執行直到結束),目的是讓父程序先與子程序結束讓子程序有個孤兒對的狀態,最後子程序再列印出其程序id(pid)以及父程序的id(pid),觀察兩次列印id(pid)的區別。

執行結果如下:

模擬實現殭屍程序, 孤兒程序

殭屍狀態是乙個比較特殊的狀態。當程序退出並且父程序 使用wait 系統呼叫 沒有讀取到子程序退出的返回 時就會產生殭屍程序。殭屍程序會終止狀態保持在程序表中,並且會一直在等待父程序讀取退出狀態 所以,只要子程序退出,父程序還在執行,但父程序沒有讀取子程序狀態,子程序進入z狀態。從上圖我們可以看出,1...

模擬實現殭屍程序和孤兒程序

殭屍程序 乙個子程序在其父程序沒有呼叫wait 或waitpid 的情況下退出。這個子程序就是殭屍程序。程序在終止時,系統會 所有核心分配給它的記憶體 關閉它開啟的所有檔案等等,但還會保留一些極少的資訊,因為 程序終止後有些資訊對於父程序和核心還是很有用的,例如程序的id號 程序的退出狀態 程序執行...

模擬實現殭屍程序和孤兒程序

首先我們來先了解一下什麼是殭屍程序和孤兒程序?當你建立了子程序後,讓父子程序幹不同的事,如果,子程序先完成事情要退出時,然後它就會等 人 來讀取它的退出狀態資訊 也就是他的父程序 這個時候,子程序就需要一直維持這這個狀態,這個狀態就是殭屍狀態 我們也稱為z狀態 也就是說,當乙個子程序退出時,他的父程...