Linux程式設計中如何避免出現殭屍程序

2021-07-11 07:54:33 字數 1931 閱讀 9751

比如程序採用exit()退出的時候,作業系統會進行一些列的處理工作,包括關閉開啟的檔案描述符、占用的記憶體等等,但是,作業系統也會為該程序保留少量的資訊,以供父程序使用。例如程序的id號、程序的退出狀態、程序執行的cpu時間等,因而占用了系統的資源。

在一種極端的情況下,檔殭屍程序過多的時候,占用了大量的程序id,系統將無法產生新的程序,相當於系統的資源被耗盡。

所以,避免殭屍程序的產生具有極其重要的意義。在 linux 下,我們可以使用 ps aux  | grep -w 'z' 等命令檢視系統中殭屍程序,殭屍程序的狀態標記為『z』。一般來講避免殭屍程序主要包含以下幾種方法:

父程序使用wait()或者waitpid()之類的函式等待子程序退出

父程序先產生乙個子程序,然後子程序再產生乙個孫子程序,子程序在孫子程序之前退出。

使用訊號函式sigaction為sigchld設定wait處理函式。

1、wait()函式的使用最為簡單,源**如圖所示:

父程序建立子程序後30s呼叫wait()函式,等待子程序退出,**子程序的資源,這也意味著子程序將會成為殭屍程序30s-5s=25s。

執行該程式後,開啟終端,檢視程序狀態,該圖顯示的有乙個程序的標誌為z,表示該程序為殭屍程序(zombie)。 

當父程序呼叫wait()函式後,子程序的資源被**,殭屍程序的標誌被去掉了.如下圖所示:

使用wait()的方法比較簡潔,但是有個問題就是子程序如果處理的時間比較長的話,主程序會被掛起。比如: 

對於這樣的情況可以採取連續fork()兩次的方法。簡而言之,首先父程序首先建立子程序,子程序建立孫子程序,由孫子程序處理事務,

而子程序再建立完孫子程序後,就退出。此時,孫子程序的父程序,也就是子程序退出了,因此孫子程序變為了乙個孤兒程序,linux程序處理

孤兒的程序的方式,是init程序接管孤兒程序,而init程序的子程序不會成為殭屍程序。

所以上述的偽**可以寫為: 

if(fork() ==0 ) 

else

} else

還有一種方法就是採用訊號量處理函式來處理這種情況,該過程的**可以表示為:

#include     

#include

#include

#include

#include

#include

int num_clients = 0;

int dead_clients = 0;

void sig_chld_handler(int sig)

}

int main(int argc, char **argv) else if (pid > 0)

}

sleep(10);

return 0;

}

父程序首先註冊乙個訊號處理函式signal(sigchld, sig_chld_handler),然後每當子程序退出的時候父程序都會受到sigchld訊號,

觸發sig_chld_handler()函式,呼叫wait()函式等待子程序的退出。  

如何避免程式設計中的BUG

這段時間的開發總是在自己給自己挖坑,進入了乙個創造bug登峰造極的階段,前兩天看了一篇類似雞湯的東西 為什麼你有10年經驗,但成不了專家 上面提到了刻意練習度的問題,很有道理,前提是你要進入 自動狀態 簡而言之就是下意識的去做出反應,但是就像有人說的,你的努力程度還到不了跟別人拼天賦的地步,還沒有到...

如何避免TreeView中Checked事件死迴圈

在treeview的aftercheck事件中新增處理 設定其它相關treenode的checked屬性。問題 通過 改變treenode.checked屬性同樣會觸發treeview.aftercheck事件。若節點a的狀態改變時需要自動改變節點b的選中狀態,且節點b的狀態改變時也需要自動改變節點...

C 中如何避免資源洩漏

請看下面一段 如果在執行delete這行 之前該片段產生異常,程式會在發生異常點停止並產生棧展開,所以不會執行delete語句,造成資源洩漏。解決的方法如下 用智慧型指標替代普通指標,當發生異常並進行棧展開過程時,程式會析構已經構造完畢的類,從而避免了資源洩漏。上面運用的是共享指標,但可以根據實際需...