Linux中的守护进程(Deamon进程)
1. 什么是守护进程?
守护进程(Daemon)是一种在后台运行的进程,不受终端控制,通常用于执行系统或服务管理任务。守护进程在系统启动时启动,并在系统运行期间一直存在,直到系统关闭。典型的守护进程如web服务器、数据库服务器等。
- 生存周期较长,独立于控制终端,通常用于周期性执行某种任务或等待任务处理事件;
- 是个特殊的**孤儿进程**;
- 可以避免由终端所产生的任何信息中断;
- Linux大多数服务器(web、数据库)都是通过守护进程实现的;
2. 创建守护进程的基本流程?
Step1 创建子进程,并终止父进程(必须)
-
在父进程中通过
fork
来创建一个子进程,并让父进程退出,确保子进程脱离控制终端。switch (fork()) //fork()出来这个子进程,根据返回值判断是父进程还是子进程; { case -1: //创建子进程失败 std::cout << "fork()失败!" << std::endl; return -1; case 0: //子进程,走到这里直接break; break; default: //父进程以往 直接退出exit(0);现在希望回到主流程去释放一些资源 return 1; //父进程直接返回1,终止; } //end switch
Step2 创建新的会话和进程组(必须)
-
使用
setsid()
创建一个新的会话,使得子进程成为会话首进程,确保进程不再依赖终端。if (setsid() == -1) { std::cout << "setsid()失败!" << std::endl; return -1; }
Step3 更换工作目录(非必须)
-
使用
chdir()
将工作目录更换为根目录,避免进程占用卸载的文件系统。if (chdir("/") < 0) { std::cerr << "Chdir failed!" << std::endl; exit(EXIT_FAILURE); }
Step4 重设文件权限掩码(非必须)
-
使用
umask()
将文件权限掩码设置为0,确保进程创建的文件具有预期权限。unmask(0);
Step5 关闭文件描述符(非必须)
- 关闭从父进程继承来的不需要的文件描述符(如标准输入、标准输出、标准错误这些与终端交互的描述符)。
- 具体实现可以重定向标准输入、输出和错误到黑洞设备 (
/dev/null
设备)。
Step6 执行守护进程核心工作(必须)
- 此时守护进程便创建好了,可以去执行后台任务了。