1、什么是守护进程?
守护进程是一个后台运行的进程,是随着系统的启动而启动,随着系统的终止而终止,类似于windows上的各种服务,比如ubuntu上的ssh服务,网络管理服务等都是守护进程。
2、守护进程的创建流程
1.创建孤儿进程(使进程能够脱离终端)(孤儿进程:子进程没结束,父进程先没了 此时该子进程就是孤儿进程。 (PS:僵尸进程:子进程死掉了 父进程还存在 但没有给它回收 ,此时死掉的子进程就变成了僵尸进程 僵尸态))
2.设置孤儿进程的会话和组id pid_t setpid(void);
3.切换目录 int chdir(const char *path)
4.修改掩码值 mode_t umask(mode_t mask)
5.创建日志文件
6.文件描述符重定向 int dup(int oldfd)或int dup2(int oldfd,int newfd)(推荐)
参考以下dup和dup2函数-CSDN博客【代码】dup和dup2函数。https://blog.csdn.net/CSDN_DU666666/article/details/139823800?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22139823800%22%2C%22source%22%3A%22CSDN_DU666666%22%7D 7.开启自己的服务
3、实例演示
#include <head.h>
int main(int argc, const char *argv[])
{
pid_t pid;
pid = fork();
if (-1 == pid)
{
perror("fork error");
exit(-1);
}
else if (pid == 0)
{
// 父进程执行exit(EXIT_SUCCESS);退出 1.子进程变成孤儿进程了
// 2.设置孤儿进程的会话和组id
if (setsid() == -1)
{
perror("setsid error");
exit(-1);
}
/*如果调用进程不是进程组领导,Setsid()将创建一个新会话。
调用进程是新会话的领导者(即,它的会话Ip与其进程ID相同)。
调用流程也成为新流程的流程组负责人。
调用流程将是新流程组和新系统中唯一的流程*/
// 3.切换目录 "var/log/"
if (chdir("/var/log/") == -1)
{
perror("chdir error");
exit(-1);
}
// 4.设置掩码
umask(0);
// 5.创建日志文件
int fd;
if (-1 == (fd = open("daemon.log", O_RDWR | O_APPEND | O_CREAT, 0666)))
{
perror("open error");
exit(-1);
}
// 6.文件描述符重定向
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
// 7.开启自己的服务
while (1)
{
printf("i am test daemon ...\n");
fflush(stdout);
sleep(3);
}
}
else
{
// 父进程
exit(EXIT_SUCCESS);
// 让父进程退出,此时子进程成为孤儿进程
// 孤儿进程:子进程没结束,父进程先没了 此时该子进程就是孤儿进程
}
return 0;
}
注:测试完成之后一定要将上述的守护进程杀死
ps -ajx |grep ./daemon 查看进程号
kill -9 pid(进程号)