Linux網絡編程學習(四) -----守護進程的建立(第三章)
本文介紹一個例程daemon_init()
#include <sys/types.h> #include <signal.h> #include <unistd.h> #include <syslog.h> #define MAXFD 64 void daemon_init(const char *pname, int facility) { int i: pid_t pid; /* fork,終止父進程 */ if (pid = fork()) exit(0); /* 第一子進程 */ setsid(); signal(SIGHUP,SIG_IGN); /* fork,終止第一子進程 */ if (pid = fork()) exit(0); /* 第二子進程 */ daemon_proc = 1; /* 將工作目錄設定為"/" */ chdir("/"); /* 清除文件掩碼 */ umask(0); /* 關閉所有文件句柄 */ for (i = 0;i < MAXFD;i++) { close(i); } /* 打開log */ openlog(pname,LOG_PID,facility); }
守護進程建立的主要過程
1、fork
通過fork出一個子進程,並把父進程關閉,這樣子進程就成了後臺進程,而且子進程從父進程哪裏繼承了組標識符同時又擁有了自己的進程標識符,這樣就保證了子進程不會是一個進程組的首進程
2、setsid
setsid()創建了一個新的進程組,調用進程成為了這個進程組的首進程,這樣就使得該進程脫離了原來的終端,成為了獨立於終端外的進程
3、忽略SIGHUP信號,重新fork
這樣使進程不再是進程組的首進程,可以放置在某些情況下的打開終端而重新與終端發生聯系
4、改變工作目錄,清除文件掩碼
改編目錄是為了切斷進程與原有文件系統的聯系,並且保證無論從什麽地方啟動進程都能正常工作,清除文件掩碼是為了消除進程自身對其創建文件的影響
5、關閉全部已經打開的文件jubing
防止子進程繼承了父進程中打開的文件而使這些文件始終保持打開狀態從而產生某些沖突
6、打開log系統
個人對這個例子的理解就是,首先該進程是一個父進程,擁有進程組標識符和進程標識符,然後通過fork創建一個子進程(第一子進程),終止父進程,但是呢,子進程雖然擁有自己的進程標識符,但卻繼承了父進程的進程組(進程組一)標識符,所以,該進程組是原先就存在的,那麽這個第一子進程就不是該進程組的首進程了。然後呢,通過setsid創建了一個新的進程組(進程組二),因為是新創建的,所以必然是首進程咯,那麽這個首進程就脫離了原先的進程環境,獨立於終端外了,然後呢,在這個新的進程組(進程組二)又重新fork出一個子進程(第二子進程),對於第二子進程來說,第一子進程就是其父進程,所以將父進程終止就是將第一子進程終止,此時,第二子進程已經獨立於原來的終端外了,並且該第二子進程也不是所屬進程組(進程組二)的首進程,最後改變工作目錄,清掩碼,關閉文件句柄,打開Log系統,那麽這個第二子進程就是創建的守護進程,嗯,我是這麽理解的,不知道理解對不對?請大神指出!
Linux網絡編程學習(四) -----守護進程的建立(第三章)