守护进程daemon

简介

daemon就是通常所说的后台进程,linux的许多服务都已这种方式实现,在后台默默运行,不会随着终端的退出和登录而改变进程状态。归纳起来其包括以下几个特点:

1、后台运行
2、守护进程与其运行前的环境相隔离。通常包括从父进程(特别是shell)中继承下来的未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩模等。
3、启动方式包括:Linux系统启动时从启动脚本/etc/rc.d中启动作业规划进程crond启动由用户终端执行&

编写daemon进程

1、为避免挂起控制终端,采用fork方式,让deamon运行实体在子进程中运行
2、为脱离控制终端,登录会话和进程组,在子进程中调用setsid()系统调用,setsid()调用成功后进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离
3、为禁止进程重新打开控制终端,再一次进行fork,然后父进程退出这样进程组长就退出了,而子进程是一个非组长进程,无法打开终端
4、关闭打开的文件描述符 、改变当前工作目录、重设文件创建掩模 、 重定向标准输入输出、处理SIGCHLD信号
实例

void BecomeDaemon(){
pid_t pid = fork();
if (pid < 0){
perror("fork error!");
exit(1);
}

if (pid > 0) //父进程
exit(0); //这里之所以不需要wait是因为,父进程立即退出,
            //子进程退出时会被当作孤儿进程被init回收

//子进程1
setsid(); //为脱离控制终端,登录会话和进程组,变成新的会话组长

pid = fork();
if (pid < 0){
perror("fork error!");
exit(1);
}

if (pid > 0) //子进程1退出
exit(0);

//子进程2 不再是会话组长
//关闭文件描述符
for (int i = 0; i < NOFILE; ++i)
close(i);

//更改工作目录
chdir("/");

//set mask
umask(0);

//重定向标准输入输出
int fp = open("/dev/null", O_RDWR);
dup2(fp, STDIN_FILENO);
dup2(fp, STDOUT_FILENO);
dup2(fp, STDERR_FILENO);

//处理SIGCHLD信号
signal(SIGCHLD, SIG_IGN);
return;
}
reference

Linux 进程、进程组、会话周期、控制终端
Linux守护进程的编程实现

你可能感兴趣的:(守护进程daemon)