守护进程特点:(1)生存期长,在系统自举的时候启动,仅在系统关闭时终止。
(2)没有控制终端,所以说他们是在后台运行的。
关于编写守护进程程序时要遵守的一些基本规则:
(1)调用umask将文件模式创建屏蔽字设置为0。(防止由继承得来的文件模式创建屏蔽字可能会拒绝设置某些权限)
(2) 调用fork(),然后使得父进程退出,这样做的目的:1.如果该守护进程是作为一条简单shell命令启动的,那么父进程终止使得shell认为这条命令已经执行完毕2.子进程继承了父进程的进程组ID,但是有一个新的进程ID,这就保证了子进程不是一个进程组的组长ID,这对于setsid调用是必要的前提条件。
(3)调用setsid创建新的对话,然后使得调用进程1.成为新会话的首进程2.成为一个新进程组的组长进程3.没有控制终端
(4)将当前工作目录更改为根目录。要确保不再装配文件系统中,因为守护进程在引导之前是一直存在的,如果守护进程的当前工作目录在一个装配文件系统中,那么该文件系统就不能被拆卸,这与装配文件系统的原意不符。
(5)关闭不再需要的文件描述符。
(6)某些守护进程打开/dev/null使其具有文件描述符0,1,2,这样任何一个试图读标准输入,写标准输入或者标准出错的库例程都不会产生任何效果。
关于守护进程代码的示例:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <time.h>
int main(int argc,char* argv[])
{
umask(0);//(1)
pid_t pid = fork();//(2)
if(pid!=0)
{
exit(0);
}
setsid();//(3)
chdir("/");//(4)
int i = 0;
for(i ;i < getdtablesize();i++)//(5)
{
close(i);
}
while(1)//守护进程的结果不能打印到终端上去,可以写到一个日志文件中去
{
time_t t;
time(&t);
FILE* fp = fopen("/tmp/testd.log","a");
fprintf(fp,"hello_bravo_:%s",asctime(localtime(&t)));
fclose(fp);
sleep(5);
}
return 0;
}