一、守护进程介绍
守护进程(Deamon process),是linux的后台服务进程。它是一个生存周期较长并且独立于控制终端的进程,通常周期性地执行某种任务或者执行某些发生的事件。守护进程是个特殊的孤儿进程,这种进程脱离终端,之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
二、编写守护进程步骤
1.首先调用umsk将文件模式创建屏蔽字设置一个已知值(通常是0)
代码如下(示例):
/*clear file creation mask*/
umask(0);
2.调用fork,然后使父进程exit
代码如下(示例):
/*Become a session leader to lose controlling TTY*/
if((pid = fork()) < 0)
err_quit("%s:can't fork",cmd);
else if(pid != 0) /*parent*/
exit(0);
3.调用setsid创建一个新会话
代码如下(示例):
setsid();
4.将当前工作目录改为根目录
代码如下(示例):
/*change the current working directory to the root so we won't prevent file system from being unmounted*/
if(chdir("/") < 0)
err_quit("%s: can't change directory to /",cmd);
5.关闭不需要的文件描述符
代码如下(示例):
/*close all open file descrictors*/
if(r1.rlim_max == RLIM_INFINITY)
r1.rlim_max = 1024;
for(i=0;i<r1.rlim_max;i++)
close(i);
6.某些守护进程打开/dev/null使其具有文件描述符0、1、2
代码如下(示例):
/*Attach file descriptors 0 , 1, and 2 to /dev/null */
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
三、daemon创建实例
代码如下(示例):
void daemonize(const char *cmd)
{
int i,fd0,fd1,fd2;
pid_t pid;
struct rlimit r1;
struct sigaction sa;
/*clear file creation mask*/
umask(0);
/*Get maximum number of file descriptors*/
if(getrlimit(RLIMIT_NOFILE,&r1) < 0)
err_quit("%s:can't get file limit",cmd);
/*Become a session leader to lose controlling TTY*/
if((pid = fork()) < 0)
err_quit("%s:can't fork",cmd);
else if(pid != 0) /*parent*/
exit(0);
setsid();
/*Ensure future opens won't allocate controlling TTYs*/
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP,&sa,NULL) < 0)
err_quit("%s: can't ignore SIGHUP",cmd);
if((pid=fork()) < 0)
err_quit("%s:can't fork",cmd);
else if(pid != 0)
exit(0);
/*change the current working directory to the root so we won't prevent file system from being unmounted*/
if(chdir("/") < 0)
err_quit("%s: can't change directory to /",cmd);
/*close all open file descrictors*/
if(r1.rlim_max == RLIM_INFINITY)
r1.rlim_max = 1024;
for(i=0;i<r1.rlim_max;i++)
close(i);
/*Attach file descriptors 0 , 1, and 2 to /dev/null */
fd0 = open("/dev/null",O_RDWR);
fd1 = dup(0);
fd2 = dup(0);
/*Initialize the log file*/
openlog(cmd,LOG_CONS,LOG_DAEMON);
if(fd0 != 0 || fd1 != 1 || fd2 != 2){
syslog(LOG_ERR,"unexpected file descriptors %d %d %d",fd0,fd1,fd2);
exit(1);
}
}
void unix_13_1_daemonize(char *name)
{
char *cmd;
if((cmd = strrchr(name,'/')) == NULL)
cmd = name;
else
cmd++;
daemonize(cmd);
}
#define UNIX_13_1_DAEMONIZE
int main(int argc, char *argv[])
{
#ifdef UNIX_13_1_DAEMONIZE
unix_13_1_daemonize(argv[0]);
#endif
printf("MAIN END\n");
return 0;
}
总结
本章主要讲解了守护进程的实现步骤以及给出了daemon进程创建实例。