1、守護程序,也就是通常說的Daemon程序,是Linux中的背景服務程序。它是一個生存期較長的程序,通常獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。如果想讓某個程序不因為使用者或終端或其他地變化而受到影響,那麼就必須把這個程序變成一個守護程序。
2、建立守護程序步驟
1)建立子程序,父程序退出
之後的所有工作都在子程序中完成,而使用者在Shell終端裡則可以執行其他指令,進而在形式上做到了與控制終端的脫離。
在Linux中父程序先于子程序退出會造成子程序成為孤兒程序,而每當系統發現一個孤兒程序時,就會自動由1号程序(init)收養它,這樣,原先的子程序就會變成init程序的子程序。
2)在子程序中建立新會話
程序組:是一個或多個程序的集合。程序組有程序組ID來唯一辨別。除了程序号(PID)之外,程序組ID也是一個程序的必備屬性。每個程序組都有一個組長程序,其組長程序的程序号等于程序組ID。且該程序組ID不會因組長程序的退出而受到影響。
會話周期:會話期是一個或多個程序組的集合。通常,一個會話開始于使用者登入,終止于使用者退出,在此期間該使用者運作的所有程序都屬于這個會話期。
(1)pid_t setsid(void);
setsid() creates a new session if the calling process is not a process group leader. The calling process will be the only process in this new process group and in this new session.
setsid函數用于建立一個新的會話,并擔任該會話組的組長。調用setsid有下面的3個作用:
① 讓程序擺脫原會話的控制
② 讓程序擺脫原程序組的控制
③ 讓程序擺脫原控制終端的控制
有以下三個結果:
(a)成為新會話的首程序
(b)成為一個新程序組的組長程序
(c)沒有控制終端。
有些人建議在此時再次調用fork,并使父程序終止。第二個子程序作為守護程序繼續運作。這樣就保證了該守護程序不是會話首程序。【4】
setsid函數能夠使程序完全獨立出來,進而擺脫其他程序的控制。
setsid()調用成功後,程序成為新的會話組長和新的程序組長,并與原來的登入會話和程序組脫離。由于會話過程對控制終端的獨占性,程序同時與控制終端脫離。
使用fork建立的子程序繼承了父程序的目前工作目錄;程序活動時,其工作目錄所在的檔案系統不能卸下。通常的做法是讓"/"作為守護程序的目前工作目錄,也可以是其他目錄,如/tmp,使用chdir。
檔案權限掩碼是指屏蔽掉檔案權限中的對應位。比如,有個檔案權限掩碼是050,它就屏蔽了檔案組擁有者的可讀與可執行權限。mask = mask & ~050
通常,把檔案權限掩碼設定為0,umask(0)。
用fork函數建立的子程序會從父程序那裡繼承已經打開了的檔案描述符。這些被打開的檔案可能永遠不會被守護程序讀寫,但它們一樣消耗系統資源,而且可能導緻所在的檔案系統無法卸下。
在上面的第二步之後,守護程序已經與所屬的控制終端失去了聯系。是以從終端輸入的字元不可能達到守護程序,守護程序中用正常方法(如printf)輸出的字元也不可能在終端上顯示出來。是以,檔案描述符為0、1和2 的3個檔案(常說的輸入、輸出和報錯)已經失去了存在的價值,也應被關閉。
for(i=0;i<MAXFILE;i++)
close(i);
當使用者需要外部停止守護程序運作時,往往會使用 kill指令停止該守護程序。是以,守護程序中需要編碼來實作kill發出的signal信号處理,達到程序的正常退出。
signal(SIGTERM, sigterm_handler);
void sigterm_handler(int arg)
{
_running = 0;
}
7)處理SIGCHLD信号
處理SIGCHLD信号并不是必須的。但對于某些程序,特别是伺服器程序往往在請求到來時生成子程序處理請求。如果父程序不等待子程序結束,子程序将成為僵屍程序(zombie)進而占用系統資源。如果父程序等待子程序結束,将增加父程序的負擔,影響伺服器程序的并發性能。在Linux下可以簡單地将 SIGCHLD信号的操作設為SIG_IGN。
signal(SIGCHLD,SIG_IGN);
這樣,核心在子程序結束時不會産生僵屍程序。
3、示例代碼
sig_atomic_t:This is an integral type of an object that can be accessed as an atomic entity, even in the presence of asynchronous signals.
示例
View Code
參考
【5】 UNIX環境進階程式設計
<a href="http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.aspx">http://www.cppblog.com/tankzhouqiang/archive/2011/06/29/149778.aspx</a>