一、守护进程
是一种在后台运行的、与终端完全脱离的进程,一般执行一些需要一直运行的任务。
是在后台运行不受终端控制的进程,一般的网络服务都是以守护进程的方式运行。
1、在 linux 中创建守护进程
(1)fork();创建子进程并关闭父进程,使新进程成为非组长进程,这是调用setsid的条件。新进程在后台运行,形式上脱离终端(并非真正脱离终端)。
(2)setsid();建立一个新会话,使调用进程:成为新会话的首进程、组长进程,并且没有控制终端。
(3)fork();关闭父进程,只保留子进程,使新进程成为非组长进程,且与终端脱离。
(4)chgdir("/");切换当前进程的目录为根目录,使原来的目录(进程的启动目录)可以被卸载。
(5)umask(0);设置:文件掩码创建屏蔽字。对,它就叫这个名字。
(6)maxfilesize;getdtablesize();关闭原来打开的所有文件描述符。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <wait.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/resource.h> // getdtablesize
#include <sys/stat.h> // umask
int main(){
pid_t pid;
// 第一步
pid = fork();
if(pid <0){
printf("fork error\n");
}
else if(pid == 0){
printf("father: %d exit\n", getpid());
exit(1);
}
sleep(1);
printf("child: %d\n", getpid());
// 第二步
setsid();
printf("new session: %d created\n", getpid());
// 第三步
pid = fork();
if(pid <0){
printf("fork error\n");
}
else if(pid > 0){
printf("father: %d exit\n", getpid());
exit(1);
}
sleep(1);
printf("child: %d\n", getpid());
// 第四步
chdir("/");
printf("chdir to /\n");
// 第五步
umask(0);
printf("umask 0\n");
// 第六步
for(int i=0; i<getdtablesize(); i++){
close(i);
}
while(1){
sleep(3);
}
return 0;
}
2、在 linux 中创建守护进程
(1) 调用fork创建子进程。父进程终止,让子进程在后台继续执行。
(2)子进程调用setsid产生新会话期并失去控制终端调用setsid()。使子进程进程成为新会话组长和新的进程组长,同时失去控制终端。
(3)忽略SIGHUP信号。会话组长进程终止会向其他进程发该信号,造成其他进程终止。
(4)调用fork再创建子进程。子进程终止,子子进程继续执行,由于子子进程不再是会话组长,从而禁止进程重新打开控制终端。
(5)改变当前工作目录为根目录。一般将工作目录改变到根目录,这样进程的启动目录也可以被卸掉。
(6)关闭打开的文件描述符,打开一个空设备,并复制到标准输出和标准错误上。 避免调用的一些库函数依然向屏幕输出信息。
(7)重设文件创建掩码清除从父进程那里继承来的文件创建掩码,设为0。
(8)用openlog函数建立与syslogd的连接。
https://blog.csdn.net/daiyudong2020/article/details/50810564