#守護程式(Daemon)是在後台運行的一種特殊進程,它脫離於終端,從而這可避免進程被任何終端所產生的信號打斷,它在執行進程中的產生資訊也不在任何終端上顯示。守護程式週期性地執行某種任務或等待處理某些發生的事件,Linux的大多數伺服器就是用守護程式實現的。
/* 处理可能的终端信号 */ signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGHUP , SIG_IGN);
/* 是父进程,结束父进程,子进程继续 */ if(fork()) exit(0);
基於上述原因,需要讓為個子進程徹底擺脫該終端的影響,需要呼叫setsid()使子進程成為新的會話組長,程式碼如下:
setsid();
setsid()呼叫成功後,呼叫此函數的程序成為新的會話組長和新的程序組長,並與原來的程序組脫離關係。由於會話過程對控制終端的獨佔性,進程同時與控制終端脫離。
/* 结束第一子进程,第二子进程继续 */ if(fork()) exit(0);
#define NOFILE 256 for(i=0; i
chdir("/tmp");
umask(0);
/* 将子进程退出信号设为SIG_IGN,让系统帮助回收进程资源 */ signal(SIGCHLD, SIG_IGN);
整體程式碼如下:
#define NOFILE 256 void DaemonMode() { int num = 0; int fd0, fd1, fd2; /* 屏蔽可能的信号 */ signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGHUP , SIG_IGN); if(fork()) exit(0); setsid(); if(fork()) exit(0); chdir("/tmp/httpd"); umask(0); for(; num
如果呼叫進程已經是一個進程組的組長,則此函數會傳回錯誤。為了杜絕這種情況,通常先呼叫fork()來建立子進程,然後使其父進程終止,而子進程繼續,在子進程中呼叫此函數。
如果呼叫此函數的進程不是一個進程組組長,則此函數會建立一個新會話,調用setsid()函數的進程成為新的會話的領頭進程,並與其父進程的會話組和進程組脫離。由於會話對控制終端的獨佔性,進程同時與控制終端脫離。
以上是剖析Linux的守護神的詳細內容。更多資訊請關注PHP中文網其他相關文章!