1.守护进程的特点
①后台服务进程
②独立于控制终端
③周期性执行某任务
④不受用户登录注销影响
⑤一般采用以d结尾的名字
2.进程组
组里边的第一个进程就是进程组的组长,进程组的ID == 进程组组长的ID。
3.会话 - 多个进程组
创建一个会话的注意事项:
①不能是进程的组长
②创建会话的进程会成为新进程组的组长
③有些linux版本需要root权限执行此操作
④创建出的新会话会丢弃原有的控制终端
⑤一般步骤:先fork出子进程,如何父进程退出,子进程执行创建会话操作
获取进程所属会话ID:
pid_t getsid(pid_t pid);
创建一个会话:
pid_t setsid(void);
4.创建守护进程模型
①fork出子进程,父进程退出(必须)
②子进程创建新会话(必须)
setsid();
③改变当前工作目录(可选)
chdir();
④重设文件掩码(可选)
子进程会继承父进程的掩码,中设掩码可增加子进程程序操作的灵活性,umask(0);
⑤关闭文件描述符(可选)
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
⑥执行核心工作(必须)
例:创建一个守护进程,每隔2s获取一次系统时间,并写入到文件中
1 #include <sys/time.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <stdio.h> 7 #include <unistd.h> 8 #include <fcntl.h> 9 #include <time.h> 10 #include <signal.h> 11 12 void myfunc(int no) 13 { 14 //打开文件 15 int fd = open("temp",O_WRONLY|O_CREAT|O_APPEND,0664); 16 //获取当前系统时间 17 time_t curtime; 18 time(&curtime); 19 //将time_t转为字符串 20 char *ptr = ctime(&curtime); 21 //写入文件 22 write(fd,ptr,strlen(ptr)+1); 23 close(fd); 24 } 25 26 int main() 27 { 28 //1.创建进程 29 pid_t pid = fork(); 30 31 if(pid > 0){ 32 exit(1); 33 }else if(pid == 0){ 34 //2.子进程创建会话 35 setsid(); 36 //3.改变当前工作目录 37 chdir("/home/czh"); 38 //4.重设文件掩码 39 umask(0); 40 //5.关闭文件描述符 41 close(STDIN_FILENO); 42 close(STDOUT_FILENO); 43 close(STDERR_FILENO); 44 //6.执行核心操作 45 46 //设置定时器 47 struct itimerval new_value; 48 //定时器第一次触发时间 49 new_value.it_value.tv_sec = 2; 50 new_value.it_value.tv_usec = 0; 51 //定时器间隔触发时间 52 new_value.it_interval.tv_sec = 1; 53 new_value.it_interval.tv_usec = 0; 54 setitimer(ITIMER_REAL,&new_value,NULL); 55 56 //注册信号捕捉 57 struct sigaction act; 58 act.sa_flags = 0; 59 sigemptyset(&act.sa_mask); 60 act.sa_handler = myfunc; 61 sigaction(SIGALRM,&act,NULL); 62 //不让进程退出 63 while(1); 64 } 65 return 0; 66 }