比如程序採用exit()退出的時候,作業系統會進行一些列的處理工作,包括關閉開啟的檔案描述符、占用的記憶體等等,但是,作業系統也會為該程序保留少量的資訊,比如程序id號等資訊,因而占用了系統的資源。在一種極端的情況下,檔殭屍程序過多的時候,占用了大量的程序id,系統將無法產生新的程序,相當於系統的資源被耗盡。
所以,避免殭屍程序的產生具有極其重要的意義。一般來講避免殭屍程序主要包含以下幾種方法:
父程序使用wait()或者waitpid()之類的函式等待子程序退出wait()函式的使用最為簡單,源**如圖所示:父程序先產生乙個子程序,然後子程序再產生乙個孫子程序,子程序在孫子程序之前退出。
使用訊號函式sigaction為sigchld設定wait處理函式。
父程序建立子程序後30s呼叫wait()函式,等待子程序退出,**子程序的資源,這也意味著子程序將會成為殭屍程序30s-5s=25s。
執行該程式後,開啟終端,檢視程序狀態,該圖顯示的有乙個程序的標誌為z,表示該程序為殭屍程序(zombie)。
當父程序呼叫wait()函式後,子程序的資源被**,殭屍程序的標誌被去掉了.如下圖所示:
2中的方法比較簡潔,但是有個問題就是子程序如果處理的時間比較長的話,主程序會被掛起。比如:
socket()對於這樣的情況可以採取連續fork()兩次的方法。簡而言之,首先父程序首先建立子程序,子程序建立孫子程序,由孫子程序處理事務,bind()
listen()
while(1)
close()
exit
}//wait()///《如果這裡父程序進行wait()操作,則很有可能再此處掛起,而如果不進行wait()操作,則此處又產生了殭屍程序。
}
而子程序再建立完孫子程序後,就退出。此時,孫子程序的父程序,也就是子程序退出了,因此孫子程序變為了乙個孤兒程序,linux程序處理
孤兒的程序的方式,是init程序接管孤兒程序,而init程序的子程序不會成為殭屍程序。
所以上述的偽**可以寫為:
if(fork() ==0 )還有一種方法就是採用訊號量處理函式來處理這種情況,該過程的**可以表示為:else
}else
#include父程序首先註冊乙個訊號處理函式signal(sigchld, sig_chld_handler),然後每當子程序退出的時候父程序都會受到sigchld訊號,#include
#include
#include
#include
#include
intnum_clients = 0;
intdead_clients = 0;
void
sig_chld_handler(
intsig)
} int
main(
intargc,
char
**argv)
else
if(pid > 0)
} sleep(10);
return
0;
}
觸發sig_chld_handler()函式,呼叫wait()函式等待子程序的退出。
上述三種方法都有好處,個人比較傾向於連續兩次fork(),這種方式我個人認為是最為簡潔的方式。
Linux下多程序避免殭屍程序的方法
include include include include include include include include include include include wait null 只要有乙個子程序退出,那麼wait就會返回 若多個子程序,只能等待乙個。while waitpid 1,...
避免殭屍程序
下面通過 為了觀察,完成同樣的功能,體會三種程序等待方式的區別。三種等待方式 1.wait waitpid 忽略sigchild訊號 忽略sigchild訊號只在linux下有效 2.wait只能進行阻塞等待,waitpid既可以用於阻塞等待,也可以用於非阻塞等待 waitpid 當waitpid的...
linux下避免殭屍程序的幾種方法
linux下我們可以呼叫fork函式建立子程序,建立的子程序將會得到父程序的資料空間 堆 棧.副本 採用寫時複製機制 子程序將會繼承父程序的訊號掩碼 訊號處理方式 當前工作目錄 會話id 組id.當子程序退出時父程序應當及時獲取子程序退出狀態,否則,如果父程序是一直在執行,那麼子程序的退出狀態將一直...