守護(hù)進(jìn)程的概念:
- 運行在后臺的一種特殊進(jìn)程.
- 不隨著 用戶的注銷 而退出.
- 獨立于終端,不能直接和用戶進(jìn)行交互.
- 周期性的執(zhí)行某種任務(wù),或者等待某些發(fā)送的事件.
創(chuàng)建守護(hù)進(jìn)程的方法:
void mydaemon(void)
{
pid_t pid;
int fd, i, nfiles;
struct rlimit rl;
pid = fork();
if(pid < 0)
ERROR_EXIT("First fork failed!");
if(pid > 0)
exit(EXIT_SUCCESS);// father exit
if(setsid() == -1)
ERROR_EXIT("setsid failed!");
pid = fork();
if(pid < 0)
ERROR_EXIT("Second fork failed!");
if(pid > 0)// father exit
exit(EXIT_SUCCESS);
#ifdef RLIMIT_NOFILE
/* 關(guān)閉從父進(jìn)程繼承來的文件描述符 */
if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
ERROR_EXIT("getrlimit failed!");
nfiles = rl.rlim_cur = rl.rlim_max;
setrlimit(RLIMIT_NOFILE, &rl);
for(i=3; i<nfiles; i++)
close(i);
#endif
/* 重定向標(biāo)準(zhǔn)的3個文件描述符 */
if(fd = open("/dev/null", O_RDWR) < 0)
ERROR_EXIT("open /dev/null failed!");
for(i=0; i<3; i++)
dup2(fd, i);
if(fd > 2) close(fd);
/* 改變工作目錄和文件掩碼常量 */
chdir("/");
umask(0);
}
解讀:
-
成為后臺進(jìn)程,用fork創(chuàng)建子進(jìn)程,父進(jìn)程退出,子進(jìn)程成為孤兒進(jìn)程被init接管仿贬,子進(jìn)程變?yōu)楹笈_進(jìn)程。
-
脫離父進(jìn)程的控制終端丰涉,登陸會話和進(jìn)程組.調(diào)用setsid()讓子進(jìn)程成為新會話的組長,脫離父進(jìn)程的會話期。setsid()在調(diào)用者是某進(jìn)程組組長時會失敗琼锋,但是A已經(jīng)保證了子進(jìn)程不會是組長后众,B之后子進(jìn)程變成了新會話組的組長胀糜。
-
禁止進(jìn)程重新開啟控制終端.因為會話組的組長有權(quán)限重新打開控制終端,所以這里第二次fork將子進(jìn)程結(jié)束蒂誉,留著孫進(jìn)程教藻,孫進(jìn)程不是會話組的組長所以沒有權(quán)利再打開控制終端,這樣整個程序就與控制終端隔離了右锨。
-
關(guān)閉文件描述符.進(jìn)程從創(chuàng)建它的父進(jìn)程那里繼承了打開的文件描述符括堤。如不關(guān)閉,將會浪費系統(tǒng)資源,造成進(jìn)程所在的文件系統(tǒng)無法卸下以及引起無法預(yù)料的錯誤痊臭。
-
重定向0,1,2標(biāo)準(zhǔn)文件描述符.將三個標(biāo)準(zhǔn)文件描述符定向到/dev/null中
-
改變工作目錄和文件掩碼.進(jìn)程活動時哮肚,其工作目錄所在的文件系統(tǒng)不能卸下(比如工作目錄在一個NFS中,運行一個daemon會導(dǎo)致umount無法成功)。一般需要將工作目錄改變到根目錄广匙。對于需要轉(zhuǎn)儲核心允趟,寫運行日志的進(jìn)程將工作目錄改變到特定目錄如chdir("/tmp"),進(jìn)程從創(chuàng)建它的父進(jìn)程那里繼承了文件創(chuàng)建掩模鸦致。它可能修改守護(hù)進(jìn)程所創(chuàng)建的文件的存取位潮剪。為防止這一點,將文件創(chuàng)建掩模清除:umask(0);