引言
精灵进程又称守护进程。进程负责程序的基本服务,但是我们也希望这种服务能够在后台持续的进程,不会因为用户的切换或者登录终端的关闭而停止。阅读本篇笔记应该补充的预备知识: 【Linux学习笔记35(补充)】精灵进程的预备知识
精灵进程代码的步骤解剖(完整代码在最下面)
- 忽略信号,防止进程因为终端关闭而被控制终端杀死:
signal(SIGHUP, SIG_IGH);
- 产生一个子进程,然后父进程立刻退出:
a = fork();
if (a >0) exit(0);
- 创建一个新会话,使得子进程在没有控制终端的新会话中运行:
setsid();
- 继续创建一个新的子进程,以确保守护进程无法被控制终端打开
a = fork();
if (a >0) exit(0);
- 将守护进程从原始进程组中分离,防止接收任何信号
setpgrp();
- 关闭任何文件描述符以释放资源
max_fd = sysconf(_SC_OPEN_MAX);
for(i=0; i<max_fd; i++)
close(i);
- 将文件权限掩码清除为零
umask(0);
- 修改当前进程的工作路径,确保不被卸载,这里设置为根。必须为根目录!(因为如果为其他路径,工作路径一旦卸载,则进程也会消失)
chdir("/");
- 来到这一步,该进程就是精灵进程了,以下添加自己需要的代码。
精灵进程的完整代码:
#include "daemon.h"
int main(void)
{
pid_t a;
int max_fd, i;
/*********************************************
1. ignore the signal SIGHUP, prevent the
process from being killed by the shutdown
of the present controlling termination
**********************************************/
signal(SIGHUP, SIG_IGN);
/***************************************
2. generate a child process, to ensure
successfully calling setsid()
****************************************/
a = fork();
if(a > 0)
exit(0);
/******************************************************
3. call setsid(), let the first child process running
in a new session without a controlling termination
*******************************************************/
setsid();
/*************************************************
4. generate the second child process, to ensure
that the daemon cannot open a terminal file
to become its controlling termination
**************************************************/
a = fork();
if(a > 0)
exit(0);
/*********************************************************
5. detach the daemon from its original process group, to
prevent any signal sent to it from being delivered
**********************************************************/
setpgrp();
/*************************************************
6. close any file descriptor to release resource
**************************************************/
max_fd = sysconf(_SC_OPEN_MAX);
for(i=0; i<max_fd; i++)
close(i);
/******************************************
7. clear the file permission mask to zero
*******************************************/
umask(0);
/****************************************
8. change the process's work directory,
to ensure it won't be uninstalled
*****************************************/
chdir("/");
// Congratulations! Now, this process is a DAEMON!
pause();
return 0;
}