#include #include #include #include #include #include void main(int argc, char ** argv)守護程序在linux/unix系統中有著廣泛的應用。有時,開發人員也想把自己的程式變成守護程序。在建立乙個守護程序的時候,要接觸到子程序、程序組、會晤期、訊號機制、檔案、目錄和控制終端等多個概念。因此守護程序還是比較複雜的,在這裡詳細地討論linux/unix的守護程序的編寫,總結出八條經驗,並給出應用範例。}
程式設計要點
1.遮蔽一些有關控制終端操作的訊號。防止在守護程序沒有正常運轉起來時,控制終端受到干擾退出或掛起。示例如下:
signal(sigttou,sig_ign); signal(sigttin,sig_ign); signal(sigtstp,sig_ign); signal(sighup ,sig_ign);
所有的訊號都有自己的名字。這些名字都以「sig」開頭,只是後面有所不同。開發人員可以通過這些名字了解到系統中發生了什麼事。當訊號出現時,開發人員可以要求系統進行以下三種操作:
◆ 忽略訊號。大多數訊號都是採取這種方式進行處理的,這裡就採用了這種用法。但值得注意的是對sigkill和sigstop訊號不能做忽略處理。
◆ 捕捉訊號。最常見的情況就是,如果捕捉到sigchid訊號,則表示子程序已經終止。然後可在此訊號的捕捉函式中呼叫waitpid()函式取得該子程序的程序id和它的終止狀態。另外,如果程序建立了臨時檔案,那麼就要為程序終止訊號sigterm編寫乙個訊號捕捉函式來清除這些臨時檔案。
◆ 執行系統的預設動作。對絕大多數訊號而言,系統的預設動作都是終止該程序。
對這些有關終端的訊號,一般採用忽略處理,從而保障了終端免受干擾。
這類訊號分別是,sigttou(表示後台程序寫控制終端)、sigttin(表示後台程序讀控制終端)、sigtstp(表示終端掛起)和sighup(程序組長退出時向所有會議成員發出的)。
2.將程式進入後台執行。由於守護程序最終脫離控制終端,到後台去執行。方法是在程序中呼叫fork使父程序終止,讓daemon在子程序中後台執行。這就是常說的「脫殼」。子程序繼續函式fork()的定義如下:
#include #include pid_t fork(void);
該函式是linux/unix程式設計中非常重要的函式。它被呼叫一次,但返回兩次。這兩次返回的區別是子程序的返回值為「0」,而父程序的返回值為子程序的id。如果出錯則返回「-1」。
3.脫離控制終端、登入會話和程序組。開發人員如果要擺脫它們,不受它們的影響,一般使用 setsid() 設定新會話的領頭程序,並與原來的登入會話和程序組脫離。這只是其中的一種方法,也有如下處理的辦法:
if ((fd = open("/dev/tty",o_rdwr)) >= 0)
其中/dev/tty是乙個流裝置,也是終端對映,呼叫close()函式將終端關閉。
4.禁止程序重新開啟控制終端。程序已經成為無終端的會話組長,但它可以重新申請開啟乙個控制終端。開發人員可以通過不再讓程序成為會話組長的方式來禁止程序重新開啟控制終端,需要再次呼叫fork函式。
上面的程式**表示結束第一子程序,第二子程序繼續(第二子程序不再是會話組長)。
5. 關閉開啟的檔案描述符,並重定向標準輸入、標準輸出和標準錯誤輸出的檔案描述符。程序從建立它的父程序那裡繼承了開啟的檔案描述符。如果不關閉,將會浪費系統資源,引起無法預料的錯誤。關閉三者的**如下:
for (fd = 0, fdtablesize = getdtablesize(); fd < fdtablesize; fd++) close(fd);
但標準輸入、標準輸出和標準錯誤輸出的重定向是可選的。也許有的程式想保留標準輸入(0)、標準輸出(1)和標準錯誤輸出(2),那麼迴圈應繞過這三者。**如下:
for (fd =3, fdtablesize = getdtablesize();fd < fdtablesize; fd++) close(fd);
有的程式有些特殊的需求,還需要將這三者重新定向。示例如下:
error=open("/tmp/error",o_wronly|o_creat,0600); dup2(error,2); close(error); in=open("/tmp/in",o_rdonly|o_creat,0600); if(dup2(in,0)==-1) perror("in"); close(in);out=open("/tmp/out",o_wronly|o_creat,0600); if(dup2(out,1)==-1) perror("out"); close(out);
6.改變工作目錄到根目錄或特定目錄程序活動時,其工作目錄所在的檔案系統不能卸下。
一般需要將工作目錄改變到根目錄或特定目錄,注意使用者對此目錄需要有讀寫權。防止超級使用者解除安裝裝置時系統報告裝置忙。
7.處理sigchld訊號。sigchld訊號是子程序結束時,向核心傳送的訊號。
如果父程序不等待子程序結束,子程序將成為殭屍程序(zombie)從而占用系統資源。因此需要對sigchld訊號做出處理,**殭屍程序的資源,避免造成不必要的資源浪費。可以用如下語句:
signal(sigchld,(void *)reap_status);
捕捉訊號sigchld,用下面的函式進行處理:
void reap_status()
8.在linux/unix下有個syslogd的守護程序,向使用者提供了syslog()系統呼叫。任何程式都可以通過syslog記錄事件。
由於syslog非常好用和易配置,所以很多程式都使用syslog來傳送它們的記錄資訊。一般守護程序也使用syslog向系統輸出資訊。syslog 有三個函式,一般只需要用syslog(...)函式,openlog()/closelog()可有可無。syslog()在shslog.h定義如下:
#include void syslog(int priority,char *format,...);
其中引數priority指明了程序要寫入資訊的等級和用途。第二個引數是乙個格式串,指定了記錄輸出的格式。在這個串的最後需要指定乙個%m,對應errno錯誤碼。
編寫Linux Unix守護程序
守護程序在linux unix系統中有著廣泛的應用。有時,開發人員也想把自己的程式變成守護程序。在建立乙個守護程序的時候,要接觸到子程序 程序組 會晤期 訊號機制 檔案 目錄和控制終端等多個概念。因此守護程序還是比較複雜的,在這裡詳細地討論linux unix的守護程序的編寫,總結出八條經驗,並給出...
python守護程序編寫
守護程序 通常被定義為乙個後台程序,而且它不屬於任何乙個終端會話 terminal session 許多系統服務由守護程式實施 如網路服務,列印等。1.呼叫fork 以便父程序可以退出,這樣就將控制權歸還給執行你程式的命令列或shell程式。需要這一步以便保證新程序不是乙個程序組頭領程序 proce...
Linux程序與守護程序的編寫試驗
1 編寫乙個程式建立乙個子程序,父程序隨後掛起,子程序迴圈列印自己的程序號和父程序號,並對比ps查詢到的程序號。2 編寫乙個程式建立n個子程序p1,p2,p3 pn,其中n由鍵盤輸入,p i 是p i 1 的父程序,列印每個程序的程序號,父程序號和子程序號。3 編寫乙個程式建立n個子程序p1,p2,...