目录
1.定义
守护进程是在操作系统后台运行的一种特殊类型的进程,它独立于前台用户界面,不与任何终端设备直接关联。这些进程通常在系统启动时启动,并持续运行直到系统关闭,或者它们完成其任务并自行终止。守护进程通常用于服务请求、管理系统或执行周期性任务。
2.控制终端
控制终端是与会话关联的终端设备,它是用户输入和输出的通道。进程通常通过其控制终端与用户交互,接收输入和向用户显示输出。对于守护进程来说,它必须从任何控制终端中脱离,确保其独立于任何用户会话在后台运行,这样才能保证其稳定性和安全性,不受用户直接控制和会话结束等事件的影响。
3.编程规则
步骤如下:
1.创建子进程并结束父进程
在UNIX和类UNIX系统中,进程是通过复制(使用fork())创建的。守护进程需要在后台独立运行。
2.设置会话ID
setsid()创建一个新会话,并使调用它的进程成为新会话的领导者,这样做的主要目的是让守护进程摆脱原来的控制终端。这样,守护进程就不会接收到终端发出的任何信号,例如挂断信号(SIGHUP),从而保证其运行不受前台用户操作的影响。
3.第二次fork()
使得守护进程不是会话领导,没有获取控制终端的能力,避免意外获取控制终端。
4.更改工作目录
将工作目录更改到根目录(/),主要是为了避免守护进程继续占用其启动时的文件系统。这对于可移动的或网络挂载的文件系统尤其重要,确保这些文件系统不需要时可以被卸载。
5.重设文件权限掩码
调用umask(0)确保守护进程创建的文件权限不受继承的umask值的影响,守护进程可以更精确地控制其创建的文件和目录的权限。
6.关闭文件描述符
守护进程通常不需要标准输入、输出和错误文件描述符,因为它们不与终端交互。关闭这些不需要的文件描述符可以避免资源泄露,提高守护进程的安全性和效率。
7.处理信号
SIGHUP 和 SIGTERM 信号。
SIGHUP:虽然守护进程和终端断开,但仍然有可能收到其它进程或内核发来的SIGHUP信号,守护进程不应该因为它而终止。
SIGTERM:SIGTERM信号是终止信号,用于请求守护进程优雅地终止。通过命令行执行kill <pid>命令可以发送SIGTERM信号,接收到这个信号之后,守护进程终止子进程,并清理回收资源,最后退出。
8.执行具体任务
这一步是守护进程的核心,它开始执行为其设计的特定功能,如监听网络请求、定期清理文件系统、执行系统备份等。
4.相关函数
4.1 setsid
#include <sys/types.h>
#include <unistd.h>
/**
* @brief 如果调用进程不是进程组的领导者,则创建一个新的会话。创建者是新会话的领导者
*
* @return pid_t 成功则返回调用进程的新会话ID,失败则返回(pid_t)-1,并设置errno以指明错误原因
*/
pid_t setsid(void);
4.2 umask
#include <sys/types.h>
#include <sys/stat.h>
/**
* @brief 设置调用进程的文件模式创建掩码。
*
* @param mask 掩码。是一个八进制数,它指定哪些权限位在文件或目录创建时应被关闭。我们通过umask(0)确保守护进程创建的文件和目录具有最开放的权限设置。
* @return mode_t 这个系统调用必然成功,返回之前的掩码值
*/
mode_t umask(mode_t mask);
4.3 chdir
#include <unistd.h>
/**
* @brief 更改调用进程的工作目录
*
* @param path 更改后的工作路径
* @return int 成功返回0,失败返回-1,并设置errno
*/
int chdir(const char *path);
4.4 openlog
#include <syslog.h>
/**
* @brief 为程序开启一个面向系统日志的连接
*
* @param iden