守护进程
概念:守护进程又叫精灵进程(Daemon Process),它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
特点:始终在后台运行,独立于任何终端,周期性的执行某种任务或等待处理特定事件。它是个特殊的孤儿进程,这种进程脱离终端。之所以脱离终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在Linux中,每一个系统于用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
举例:http服务的守护进程是httpd,mysql服务的守护进程是mysqld。
命令创建守护进程:nohup xxx &
守护进程实现流程
1、创建子进程,父进程直接结束
2、创建新的会话,让当前进程成为该会话组的组长 setsid
3、改变目录到根目录(不可被卸载的目录) chdir
4、重设权限掩码 umask
5、关闭所有的文件描述符 getdtablesize
setsid:创建一个新的会话,使当前进程成为会话组组长,使得该进程脱离所有进程的控制。该函数成功返回为会话ID,失败返回-1。
chdir:改变工作主目录,函数传递的参数为想改变的操作路径的路径名。该函数成功返回0,失败返回-1。
umask:重设文件掩码,函数传参为重设的文件掩码的值,一般设定为0。后续守护进程创建的文件权限可以随意由守护进程决定。
getdtablesize:获取当前打开的文件描述符的个数,函数无需传参。该函数成功返回文件描述符个数,失败返回-1。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
int main() {
// 创建子进程
pid_t pid;
pid = fork();
// 判断是否创建成功
if(pid < 0) {
perror("fork");
return -1;
}
// 1、父进程退出
if(pid > 0) {
exit(0);
}
// 子进程执行以下内容
// 2、改变当前进程为会话组组长
if(setsid() < 0) {
perror("setsid");
exit(0);
}
// 3、更改当前的工作目录
if(chdir("/") < 0) {
perror("chidr");
exit(0);
}
// 4、设置文件掩码
if(umask(0) < 0) {
perror("umask")
exit(0);
}
// 5、关闭所有的文件描述符
int size = getdtablesize();
int i;
for(i = 0; i < size; i++) {
close(i);
}
return 0;
}