守護進程

概念

    守護進程,也就是通常說的Daemon進程,是Linux中的後臺服務進程。它是一個生存期較長的進程,通常獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護進程常常在系統引導裝入時啓動,在系統關閉時終止。Linux系統中大多數服務和系統任務都是通過守護進程實現的。例如,作業規劃進程crond、打印進程lqd、nfsd、lockd、rpciod(這三個是NFS的守護進程)、portmap(端口映射守護進程提供將RPC程序號映射爲port好的服務)、bdflush(當內存達到下限時,將buffer cache flush到磁盤上)、kupdated(每隔一段時間,kupdated將dirty page flush到磁盤上以免數據丟失)、syslogd(由幫助操作人員把系統消息記入日誌的任何程序使用)、crond(指定的日期和時間執行命令)。
 
 
創建守護進程
(1).創建子進程,父進程退出,這樣讓init收養子進程。
(2).調用setsid子進程中創建新會話
  會話週期:會話期是一個或多個進程組的集合。通常,一個會話開始與用戶登錄,終止於用戶退出,在此期間該用戶運行的所有進程都屬於這個會話期。
  setsid函數用於創建一個新的會話,並擔任該會話組的組長。調用setsid有下面的3個作用:
  讓進程擺脫原會話的控制
  讓進程擺脫原進程組的控制
  讓進程擺脫原控制終端的控制
  子進程全盤繼承了了父進程的會話期、進程組、控制終端等,雖然父進程退出了,但會話期、進程組、控制終端等並沒有改變,因此,還還不是真正意義上的獨立開來,而setsid函數能夠使進程完全獨立出來,從而擺脫控制終端和其他進程的控制。
(3).改變當前目錄(一般爲根目錄)
  這一步也是必要的步驟。使用fork創建的子進程繼承了父進程的當前工作目錄。由於在進程運行中,當前目錄所在的文件系統(如“/mnt/usb”)是不能卸載的,這對以後的使用會造成諸多的麻煩(比如系統由於某種原因要進入單用戶模式)。因此,通常的做法是讓"/"作爲守護進程的當前工作目錄,這樣就可以避免上述的問題,當然,如有特殊需要,也可以把當前工作目錄換成其他的路徑,如/tmp。改變工作目錄的常見函數式chdir。
(4).重設文件權限掩碼umask(0)。
(5).關閉文件描述符
  同文件權限碼一樣,用fork函數新建的子進程會從父進程那裏繼承一些已經打開了的文件。這些被打開的文件可能永遠不會被守護進程讀寫,但它們一樣消耗系統資源,而且可能導致所在的文件系統無法卸下。
  在上面的第二步之後,守護進程已經與所屬的控制終端失去了聯繫。因此從終端輸入的字符不可能達到守護進程,守護進程中用常規方法(如printf)輸出的字符也不可能在終端上顯示出來。所以,文件描述符爲0、1和2 的3個文件(常說的輸入、輸出和報錯)已經失去了存在的價值,也應被關閉。通常按如下方式關閉文件描述符:
for(i=0;i<MAXFILE;i++)
close(i);
其他一些慣例:
(1).要保證守護進程運行唯一副本,一般使用文件鎖或記錄鎖。鎖文件放在/var/run/deamon_name.pid
(2).鎖的選項文件通常放在/etc目錄中,配置文件是deamon_name.conf
(3).守護進程可以由命令行啓動。通常他們是由初始化腳本之一/etc/init.d/*啓動。如果守護進程終止時應該自動重新啓動,可以在inittab爲該守護進程設置respawn記錄項。這樣init就會自動啓動該守護進程。
(4).由於守護進程不與終端關聯,它們是無控制終端的會話首進程或者孤兒進程組成員,所以SIGHUP信號可以用於其他用途,比如當管理員更改了配置文件,守護進程不需要重啓動將讀重新應用配置文件的操作設置爲SIGHUP信號處理程序。(一般更新配置文件後運行一個update-config程序來發送信號給守護進程)。
 
日誌消息
有三種方法產生日誌消息:
(1).內核調用log函數,任何一個用戶通過open&read /dev/klog設備就可以讀這些消息。
(2).大多數用戶進程(守護進程)調用syslog函數產生日誌消息,這使消息發送到UNIX域數據報嵌套字/dev/log。
(3).在此主機上的一個用戶進程或通過TCP/IP網絡鏈接到此主機的其他主機上的用戶進程可將日誌消息發送到UDP514端口。
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
int setlogmask(int maskpri);
ident一般是程序名稱(cron, inetd等),例如在一個打印機加假脫機守護進程中,可能包含下面的調用序列:
open("lpd", LOG_PID, LOG_LPR); /*LOG_PID表示每條消息包含lpd守護進程的pid, LOG_LPR爲行打印*/
syslog(LOG_ERR,“error in opening file:%s:%m”, filename) /*LOG_ERR是守護進程的priority*/
 
保證一個時間運行一個守護進程的副本:使用文件鎖或記錄鎖
#define LOCKFILE "/var/run/deamon.pid" /*慣例來說鎖文件放在這個目錄下,文件名name.pid*/
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
fd=open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
if (lockfile(fd) != 0) {
if(errno == EACCES || errno == EAGAIN) {
/*守護進程正在運行*/
close(fd);
return(1);
}
syslog(...); /*其他錯誤*/
exit(1);
}
ftruncate(fd,0);
sprintf(buf, "%ld", (long)getpid());
write...
return(0);
 
chkconfig
chkconfig命令也可以用來激活和解除服務。chkconfig--list命令顯示系統服務列表,以及這些服務在運行級別0到6中已被啓動(on)還是停止(off)。chkconfig還能用來設置某一服務在某一指定的運行級別內被啓動還是被停運。例如,要在運行級別3、4、5中停運nfs服務,使用下面的命令:
chkconfig --level 345 nfs off
 
 
網絡編程中C/S守護進程模型
    在C/S模式下,服務器監聽(Listen)在一個特定的端口上等待客戶連接。連接成功後服務器和客戶端通過端口進行數據通信。守護進程的工作就是打開一個端口,並且等待(Listen)進入連接。如果客戶端產生一個連接請求,守護進程就創建(Fork)一個子服務器響應這個連接,而主服務器繼續監聽其他的服務請求。
獨立運行的守護進程由init腳本負責管理,所有獨立運行的守護進程的腳本在/etc/rc.d/init.d/目錄下。系統服務都是獨立運行的守護進程包括:syslogd和cron等。運行獨立的守護進程工作方式稱爲stand-alone。它UNIX傳統的C/S模式的訪問模式。服務器監聽在一個特點的端口上等待客戶端的連接。如果客戶端產生一個連接請求,守護進程就創建一個子服務器響應這個連接,而主服務器繼續監聽。以保持多個子服務器池等待下一個客戶端請求。
    工作在stand-alone模式下的網絡服務有route、gated。另外是大家最熟悉是Web服務器:Apache和郵件服務器Sendmail、域名服務器Bind。因爲這些負載很大服務器上,預先創子服務器,可以通過客戶的服務速度。在Linux系統中通過stand-alone工作模式啓動的服務由/etc/rc.d/下面對應的運行級別當中的符號鏈接啓動。
    從守護進程的概念可以看出,對於系統所要通過的每一種服務,都必須運行一個監聽某個端口連接所發生的守護進程,這通常意味着資源浪費。爲了解決這個問題,Linux引進了"網絡守護進程服務程序"的概念。Redhat Linux 9以後版本使用的網絡守護進程是xinetd(eXtended InterNET daemon)。和stand-alone模式相比,xinted模式也稱Internet Super-Server(超級服務器)。xinetd能夠同時監聽多個指定的端口,在接受用戶請求時,它能夠根據用戶請求的端口不同,啓動不同的網絡服務進程來處理這些用戶請求。可以把xinetd看做一個管理啓動服務的管理服務器,它決定把一個客戶請求交給那個程序處理,然後啓動相應的守護進程。
    和stand-alone工作模式相比,系統不想要每一個網絡服務進程都監聽其服務端口。運行單個xinetd就可以同時監聽所有服務端口,這樣就降低了系統開銷,保護了系統資源。但是當訪問量大、經常出現併發訪問時,xinetd想要頻繁啓動對應的網絡服務進程,反而會導致系統性能下降。查看系統爲Linux服務提供哪種模式方法在Linux命令行可以使用pstree命令,可以看到兩種不同方式啓動的網絡服務。一般來說一些負載高的服務如sendmail、Apache服務是單獨啓動的。而其他服務類型都可以使用xinetd超級服務器管理。
 
Reference
APUE
baike.baidu.com
http://www.unlinux.com/doc/net/20051028/5950.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章