守护进程
运行周期长,在后台运行,不和用户交互
会话:会话是一个或多个进程组的集合。
会话首进程:创建此会话的进程,会话首进程的进程ID是会话ID,首进程是其所在的进程组的组长进程,因为在其创建一个会话的同时已经变成了一个组长进程。
进程组:每个进程属于一个进程组,进程组是一个或多个进程的集合,每个进程有一个唯一的进程组ID。
组长进程:每个进程组可以有个组长进程,组长进程的ID就是进程组的ID;组长进程可以创建进程组以及该组中的进程;进程组的创建从第一个进程(组长进程)加入开始;进程组的组号取第一个加入组的进程(组长进程)编号;
1、守护进程本质其实是一个孤儿进程
2、守护进程自成进程组,自成会话
3、守护进程与终端无关
守护进程和后台进程的区别:
1、后台进程受用户登录和注销的影响,而守护进程不受用户登录和注销的影响
2、守护进程已经完全脱离终端控制台了,而后台程序并未完全脱离终端(在终端未关闭前还是会往终端输出结果)
3、守护进程的会话组和当前目录,文件描述符都是独立的。后台运行只是终端进行了一次fork,让程序在后台执行,这些都没改变
编程流程:
fork() 退出父进程
setsid()
fork() 退出父进程
chdir("/")
umask(0)
close()
处理僵死进程
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <time.h>
#include <sys/stat.h>
int main()
{
pid_t pid=fork();
if(pid!=0)
{
exit(0);
}
setsid();
pid_t pid=fork();
if(pid!=0)
{
exit(0);
}
chdir("/");
umask(0);
int maxfd=getdtabesize();
for(int i=0;i<maxfd;i++)
{
close(i);
}
while(1)
{
FILE *fp=fopen("/tmp/c117d.log","a");
if(fp==NULL)
{
break;
}
time_t tv;
time(&tv);
fprintf(fp,"Time is %sn",asctime(localtime(&tv)));
fclose(fp);
sleep(5);
}
}
快速查看日志文件:tail -f <文件名>