在一個遠程監控系統中,咱們使用了守候進程。結合《Linux高級程序設計》的相關內容,對守候進程作個整理。編程
守候進程,又稱守護進程(Daemon),是在後臺運行的一種特殊的進程,脫離於終端。相似於Windows服務程序。守候進程適用於像咱們項目中的數據採集類的程序,由於客戶的誤操做等緣由,形成服務器的重啓,這時要保證數據的接收是正常的,那麼,頗有必要將採集程序運行在後臺,不被顯示的終端界面所影響。服務器
咱們使用在系統啓動時,隨啓動腳原本啓動守候進程, 在/etc/rc.local里加上一句 /usr/local/haven/Daemon(即你的程序所在路徑)。併發
守候進程的編程步驟通常比較死,都是規定好的,是一個套路:ide
一、屏蔽一些有關控制終端操做的信號;防止在守護進程沒有正常運行起來前,控制終端收到干擾退出或掛起。性能
二、在後臺運行,爲了不掛起控制終端將其放入後臺執行。spa
三、脫離控制終端和進程,控制終端和進程組是從父進程繼承下來的,要擺脫他們,使子進程成爲新的會話組長。.net
4.、禁止進程從新打開控制終端,由於能夠從新申請打開一個控制終端,那麼再建立一個子進程。設計
5.、關閉打開的文件描述符,若不關閉會浪費系統資源。日誌
六、改變當前工做目錄,進程工做時,其工做目錄在文件系統不能寫下的。所以放在根目錄,寫運行日誌的進程將工做目錄改變到特定目錄。繼承
七、重設文件建立掩碼。
八、處理SIGCHLD信號(子進程退出信號)。對於某些,特別是服務器進程每每在請求到來時生成子進程處理請求。若是父進程不等待子進程結束,子進程將成爲殭屍進程從而佔用了資源,若是父進程等待子進程結束,將增長父進程的負擔,影響服務器進程的併發性能。從而使用此步驟來解決這一問題。
下面是一個簡單實現:Daemon.c
- #include<unistd.h>
- #include<signal.h>
- #include<fcntl.h>
- #include<sys/syslog.h>
- #include<sys/param.h>
- #include<sys/stat.h>
- #include<stdio.h>
- #include<stdlib.h>
- int init_daemon(const char *pname,int facility)
- {
- int pid;
- int i;
- signal(SIGTTOU,SIG_IGN); //處理可能的終端信號
- signal(SIGTTIN,SIG_IGN);
- signal(SIGTSTP,SIG_IGN);
- signal(SIGHUP ,SIG_IGN);
- if(pid=fork()) //建立子進程,父親進程退出
- {
- exit(EXIT_SUCCESS);
- }
- else if(pid<0)
- {
- perror("fork");
- exit(EXIT_FAILURE);
- }
- setsid(); //設置新會話組長,新進程組長,脫離終端
- if(pid=fork()) //建立新進程,子進程不能再申請終端
- {
- exit(EXIT_SUCCESS);
- }
- else if(pid<0)
- {
- perror("fork");
- }
- for(i=0;i<NOFILE;++i) //關閉父進程打開的文件描述符
- close(i);
- open("/dev/null",O_RDONLY); //對標準輸入所有從新定向到文件中
- open("/dev/null",O_RDWR);
- open("/dev/null",O_RDWR);
- chdir("/tmp"); //修改主目錄
- umask(0); // 重建設置文件掩碼
- signal(SIGCHLD,SIG_IGN); //處理子進程退出
- openlog(pname,LOG_PID,facility); //與守護進程創建聯繫,加上進程號,文件名
- return ;
- }
- int main(int argc ,char *argv[])
- {
- FILE *fp;
- time_t ticks;
- init_daemon(argv[0],LOG_KERN);//執行守候進程
- while(1)
- {
- sleep(1);
- ticks=time(NULL);
- syslog(LOG_INFO, "%s", asctime(localtime(&ticks))); //寫日誌信息
- }
- }
編譯運行:
[root@localhost haven]# gcc -o Daemon Daemon.c
[root@localhost haven]# ./Daemon
查看:
[root@localhost haven]# ps aux|grep Daemon
root 13021 0.0 0.0 1648 420 ? S 14:26 0:00 ./Daemon
root 13092 0.0 0.0 3916 660 pts/1 R+ 14:28 0:00 grep Daemon
查看日誌:
[root@localhost haven]# tail /var/log/messages
Feb 29 14:28:53 localhost ./Daemon[13021]: Wed Feb 29 14:28:53 2012
Feb 29 14:28:54 localhost ./Daemon[13021]: Wed Feb 29 14:28:54 2012
Feb 29 14:28:55 localhost ./Daemon[13021]: Wed Feb 29 14:28:55 2012
Feb 29 14:28:56 localhost ./Daemon[13021]: Wed Feb 29 14:28:56 2012
Feb 29 14:28:57 localhost ./Daemon[13021]: Wed Feb 29 14:28:57 2012
Feb 29 14:28:58 localhost ./Daemon[13021]: Wed Feb 29 14:28:58 2012
Feb 29 14:28:59 localhost ./Daemon[13021]: Wed Feb 29 14:28:59 2012
Feb 29 14:29:00 localhost ./Daemon[13021]: Wed Feb 29 14:29:00 2012
Feb 29 14:29:01 localhost ./Daemon[13021]: Wed Feb 29 14:29:01 2012
Feb 29 14:29:02 localhost ./Daemon[13021]: Wed Feb 29 14:29:02 2012
by HavenZhao http://vcsky.net