守护进程模型创建思路及详细实现代码
Daemon(精灵)进程,是Linux中的后台服务进程,通常独立于控制终端并且周期性的执行某种任务或者等待处理某些发生的事件,一般采用以d结尾的名字。
特点:
没有控制终端,不能直接和用户交互,不受用户登录,注销的影响,一直运行着
创建守护进程模型:
1,创建子进程,父进程退出
2,在子进程中创建新会话,可使用setsid()函数,使子进程完全独立
3,改变当前目录为根目录,可使用chdir()函数,防止占用可卸载的文件系统
4,重设文件权限掩码,umask()函数 ,防止继承的文件创建屏蔽某些权限
5,关闭文件描述符,继承的打开不会用到
6,开始执行守护进程核心工作
7,守护进程退出处理
具体实现代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <sys/time.h> #include <signal.h> #include <sys/stat.h> #include <errno.h> int fd; //信号处理函数 void sighandler(int signo) { //获取系统时间 time_t tm; time(&tm); char *p = ctime(&tm); write(fd, p, strlen(p)); } int main() { pid_t pid; int ret; //创建一个子进程, 然后父进程退出 pid = fork(); if(pid<0 || pid>0) { exit(0); } //子进程创建新会话 setsid(); //改变当前工作目录chdir chdir("/home/pig/test"); //重设文件掩码 umask(0000); //关闭文件描述符 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); //打开一个文件 fd = open("./test.log", O_RDWR | O_CREAT, 0777); if(fd<0) { perror("open error"); return -1; } //注册信号处理函数 struct sigaction act; act.sa_handler = sighandler; act.sa_flags = 0; sigemptyset(&act.sa_mask); sigaction(SIGALRM, &act, NULL); //调用setitimer函数定时发送SIGALRM信号 struct itimerval tm; tm.it_interval.tv_sec = 2; tm.it_interval.tv_usec = 0; tm.it_value.tv_sec = 3; tm.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &tm, NULL); while(1) { sleep(2); } close(fd); return 0; }