简介
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;
}
网友评论