守护进程
1.特点:
后台服务
独立于控制终端
周期性的执行任务
不受用户登陆注销影响
一般采用以d结尾的名字(服务)
2.进程组
[1]进程的组长?
组里边的第一个进程
进程组的ID==进程组的组长的ID
[2]进程组组长的选择
进程中的第一个进程
[3]进程组ID的设定
进程组的ID就是组长的进程ID
3.会话:多个进程组
1.创建一个会话注意事项
不能是进程组组长
创建会话的进程称为新进程组的组长
创建出的新会话会丢弃原有的控制终端
2.获取进程所属的会话ID
3.创建一个会话
pid_t setsid();
4.创建守护进程模型
fork子进程,父进程退出
在子进程中:
setsid();
chdir("/");
umask(0);
close(0);close(1);close(2);
后台服务进程
案例
/*
写一个守护进程,每隔1s获取当前系统时间,并写入本地磁盘
*/
void handler(int no){
//获取当前系统时间curtime
time_t curtime;
time(&curtime);
//将curtime使用ctime转换成char*类型
char* pt=ctime(&curtime);
int fd=open("/home/gjw/time.log",O_CREAT|O_RDWR|O_APPEND,0664);
write(fd,pt,strlen(pt)+1);
close(fd);
}
int main(){
pid_t pid=fork();
if(pid==-1){
perror("fork");
exit(1);
}
else if(pid>0){
exit(1);
#if 0
kill(getpid(),SIGKILL);
raise(SIGKILL);
abort();
#endif
}
else if(pid==0){
setsid(); //变成会长-脱离终端控制
chdir("/home/gjw");//改变当前工作目录
umask(0);//重置文件掩码
close(0); //关闭文件描述符,释放资源
close(1);
close(2);
//sigaction:信号SIGALRM处理函数
//signal(SIGALRM,handler);
struct sigaction act;
act.sa_flags=0;
act.sa_handler=handler;
sigemptyset(&act.sa_mask);
sigaction(SIGALRM,&act,NULL);
//设置周期定时器
struct itimerval tim;
tim.it_value.tv_sec=2;
tim.it_value.tv_usec=0;
tim.it_interval.tv_sec=1;
tim.it_interval.tv_usec=0;
setitimer(ITIMER_REAL,&tim,NULL);
while(1); //守护进程一直while,不退出
}
return 0;
}