守护进程创建方法
守护进程是什么:
守护进程又叫精灵进程,是一个生存期较长的进程,通常独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。它是一个在后台运行的孤儿进程,这使得守护进程不受终端的信息影响(比如ctrl c中断程序),同时守护进行也不能够向终端发送任何信息(标准输入、标准输出、标准错误被关闭)。
具体创建步骤如下:
- 创建子进程,父进程退出。这使得子进程变为孤儿进程,被init收养后在后台运行。
- 创建新的会话。这使得子进程成为新的会话组长,脱离原来的会话和进程组。
- 改变当前工作目录。这一步非必须,目的是让守护进程的工作目录不能被卸载。
- 重设文件掩码。这一步非必须,目的是创建文件时,权限不受系统默认掩码影响。
- 关闭标准输入、标准输出、标准错误。这使得子进程不能和终端进行信息交互。
具体代码实现如下:
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
int main(){
pid_t pid;
//1.创建子进程,父进程退出
if((pid = fork())<0){
perror("fork");
return -1;
}else if(pid > 0){
exit(0);//父进程退出
}
//2.建立新的会话
//printf("Debug:before setsid():pid = %d,pgid = %d,sid = %d\n",getpid(),getpgid(getpid()),getsid(getpid()));
if(setsid()<0){
perror("setsid");
exit(0);
}
//printf("Debug:after setsid():pid = %d,pgid = %d,sid = %d\n",getpid(),getpgid(getpid()),getsid(getpid()));
//3.更改工作目录
chdir("/");//将工作目录改为根目录,确保工作目录不被卸载
//4.重设文件掩码
umask(0);//设置掩码为0000
//5.关闭标准输入、标准输出、标准错误
close(0);
close(1);
close(2);
/*
守护进程功能代码
........
*/
return 0;
}
存在的一些问题:
创建子进程,父进程退出后,通过ps -elf | grep xxx 查询,发现父进程的进程号不是1
问题如下图:
原因:这是因为init有许多事情做,在init中创建了一个子进程专门用来收留孤儿进程。
相关函数
1、终端创建守护进程
nohup <程序名> &
2、创建新的会话
函数声明如下:
pid_t setsid(void);
返回值:成功返回调用进程的会话ID,失败返回-1
注意:调用了setsid的进程,既是新的会长,也是新的组长。
3、更改当前的工作目录
函数声明如下:
int chdir(const char *path);
返回值:成功返回0,失败返回-1
path:新的工作目录
4、重设文件权限掩码
函数声明如下:
mode_t umask(mode_t mask);
mask:掩码
注意:这个设置的掩码只影响当前进程,其余进程不受影响。