守护进程
-
会话: 进程组的更高一级,多个进程对应一个会话。
-
进程组: 多个进程在同一个组,第一个进程默认时进程组的组长,创建会话的时候,组长不可以创建,必须是组员创建
-
创建会话的步骤:创建子进程,父进程去死,子进程自当会长
-
守护进程的步骤
- 创建子进程fork
- 父进程退出
- 子进程当会长 setsid
- 切换工作目录 $HOME
- 设置掩码 umask
- 处理SIGCHLD信号
- 如果屏蔽了SIGCHLD信号,内核会把僵尸子进程转交给init进程处理 signal(SIGCHLD, SIG_IGN);
- 处理SIGCHLD信号
- 关闭文件描述符0,1,2为了避免浪费资源
- 执行核心逻辑
- 退出
-
通过nohup指令也可以达到守护进程创建的效果
- 例:nohup cmd [> 1.log] &
- nohup指令会让cmd收不到SIGHUP信号
- & 代表后台运行
void sigCatchFun(int num)
{
char *HomeDir = getenv("HOME");
char strFileName[256]={0};
sprintf(strFileName,_FILE_NAME_FORMAT_,HomeDir,time(NULL));
int fd = open(strFileName,O_WRONLY|O_CREAT,0666);
if(fd < 0)
{
perror("open err\n");
exit(-1);
}
close(fd);
}
int main()
{
//创建子进程
pid_t pid = 0;
pid=fork();
if(pid > 0)
//父进程退出
exit(1);
//子进程当会长
setsid();
//设置掩码 子进程从其父进程继承的文件的权限掩码,可能会修改守护进程所创建的文件权限,需要将掩码清楚。
umask(0);
//切换工作目录
chdir(getenv("HOME"));
//关闭文件描述符
//close(1),close(0),close(2)
//执行核心逻辑
// 自定义定时器 #include <sys/time.h>
//struct itimerval oldSendSig,sendSig={{60,0},{60,0}};
struct itimerval oldSendSig,sendSig={{60,0},{1,0}};
setitimer(ITIMER_REAL,&sendSig,&oldSendSig);
//注册捕捉函数 #include <signal.h>
struct sigaction act;
act.sa_flags=0;
act.sa_handler = sigCatchFun;
sigemptyset(&act.sa_mask);
//sigaddset(&%1.sa_mask,SIGINT);
sigaction(SIGALRM,&act,NULL);
while(1)
//每隔一分钟在$PATH/log下创建文件
sleep(1);
//退出
return 0;
}